#Part 1 The purpose of this notebook is to determine the selective benefit of glucosinolate and flavonoid compounds through plant competition by creating selection gradients. Selection gradients will involve final body mass as the proxy for fitness, but this will be replaced with fitness once the measurement is in. Concentration will be on the x-axis. This analysis will account for family and greenhouse location.
#Part 2 The second purpose is to determine if glucosinolates and flavonoids influence suscpetibility to pathogens and if this susceptibility results in increased fitness
#Read in and prep data
library(ggplot2)
Warning messages:
1: Unknown or uninitialised column: `WhiteFungLogis`.
2: Unknown or uninitialised column: `WhiteFungLogis`.
3: Unknown or uninitialised column: `WhiteFungLogis`.
4: Unknown or uninitialised column: `WhiteFungLogis`.
library(lme4)
library(tidyr)
library(cowplot)
library(grid)
library(gridExtra)
library(dplyr)
source("GGPlot_Themes.R")
#read in data
rm(list=ls())
dat<-read.csv("DataSynthesis.csv")
#Remove maple controls data from the data set.
dat<-dat %>% filter(treatment!="mcnt") %>% droplevels()
#Assign family column
prefamily<-gsub("*.\\|","",dat$Tag)
dat$Family<-gsub("\\-.*","",prefamily)
#remove those with fertilizer treatment, and extra genotypes that are only in the alone treatment.
dat<-dat[!grepl("i",dat$Sample,fixed=T),]
#Initializing columns to avoid constant error messages.
dat$WhiteFungLogis<-NA
dat$BlackFungLogis<-NA
#Generating data frames with summarized leaf data (dat2) and summarized genotype data (dat3)
#Summarizing: Taking the mean value of leaves. This tibble contains data at the level of the plant means.
dat2<-dat %>% group_by(Tag) %>% summarize(ChlorA=mean(ChlorA),ChlorB=mean(ChlorB),gluc_Conc=mean(gluc_Conc),flav_Conc=mean(flav_Conc),Family=first(Family),treatment=first(treatment),gh_row=first(gh_row),gh_bench=first(gh_bench),GM_TotalLeaf_Area=first(GM_TotalLeaf_Area),comp_number=first(comp_number),ThripsDam=mean(ThripsDam),WhiteFungDam=mean(WhiteFungDam),BlackPathDam=mean(BlackPathDam),Fern=mean(Fern),gh_col=first(gh_col))
dat
#All of these genotypes died (15 Genotypes).(We are simply missing a final measurement for e|JBCHY1-1-50|Q|240) That is only 3% Mortality.
dead<-dat2[is.na(dat2$GM_TotalLeaf_Area),]
#Removing those with dead competitors from the garlic mustard treatment. ("e|JBCHY1-1-50|Q|240") did not die, we are simply missing the final measurement for it.
dead_competitors<-dead %>% filter(treatment=="gm",Tag!="e|JBCHY1-1-50|Q|240") %>% select(comp_number)
#Removing those with dead competitors from the analysis.
dat2<-dat2 %>% filter(!comp_number %in% dead_competitors$comp_number)
##Summarizing: Taking the mean value of plants. This tibble contains data at the level of the family means within each treatment.
dat3<-dat2 %>% drop_na(GM_TotalLeaf_Area) %>% group_by(Family,treatment) %>% summarize_if(is.numeric,mean)
#Searching for a fitness trade-off between the alone and interspecific competition treatment.
source("GGPlot_Themes.R")
#Calculating family means within treatment.
TradeOff<-dat3 %>% filter(treatment=="a") %>% drop_na(GM_TotalLeaf_Area) %>% select(LeafSizeAlone=GM_TotalLeaf_Area,Family,gluc_ConcAlone=gluc_Conc) %>% right_join(dat3 %>% filter(treatment=="m") %>% select(LeafSizeMaple=GM_TotalLeaf_Area,Family,gluc_ConcMaple=gluc_Conc),by="Family")
#Calculating standard error of each family
StdErr<-dat2 %>% select(Family,treatment,GM_TotalLeaf_Area) %>% group_by(Family,treatment) %>% drop_na(GM_TotalLeaf_Area) %>% summarize(StdErr=sd(GM_TotalLeaf_Area)/sqrt(length(GM_TotalLeaf_Area)),size=length(GM_TotalLeaf_Area))
#Shifting the data to be in long form.
StdErr2<-StdErr %>% filter(treatment=="a") %>% select(StdErrAlone=StdErr,Family) %>% right_join(StdErr %>% filter(treatment=="m") %>% select(StdErrMaple=StdErr,Family),by="Family")
TradeOff2<-StdErr2 %>% left_join(TradeOff)
Joining, by = "Family"
#tiff("Selection_Figures/TradeOff.tiff", units="in", width=10, height=6, res=300)
ggplot(TradeOff2,aes(y=LeafSizeAlone,x=LeafSizeMaple))+
geom_point()+
geom_linerange(aes(ymin = LeafSizeAlone - StdErrAlone,
ymax = LeafSizeAlone + StdErrAlone))+
geom_errorbarh(aes(xmin = LeafSizeMaple - StdErrMaple,
xmax = LeafSizeMaple + StdErrMaple))+
theme_simple()+
xlab("Performance with Maple")+
ylab("Performance Alone")

#dev.off()
summary(lm(LeafSizeAlone~LeafSizeMaple,data=TradeOff2))
Call:
lm(formula = LeafSizeAlone ~ LeafSizeMaple, data = TradeOff2)
Residuals:
Min 1Q Median 3Q Max
-2019.5 -657.0 -265.5 907.7 2364.0
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 9590.03571 1616.26626 5.933 6.87e-06 ***
LeafSizeMaple -0.00936 0.18258 -0.051 0.96
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 1244 on 21 degrees of freedom
Multiple R-squared: 0.0001251, Adjusted R-squared: -0.04749
F-statistic: 0.002628 on 1 and 21 DF, p-value: 0.9596
#Visualizing genetic variation and greenhouse variation, which will be controlled for.
#GH Bench
ggplot(dat2)+
geom_point(aes(y=gluc_Conc,x=gh_bench,colour=as.factor(gh_bench)))

#GH Col
ggplot(dat2)+
geom_point(aes(y=gluc_Conc,x=gh_col,colour=as.factor(gh_bench)))

#Investigating genetic differences by treatment
#gluc_Conc
boxplot(gluc_Conc~Family,data=dat2[dat2$treatment=="a",])

boxplot(gluc_Conc~Family,data=dat2[dat2$treatment=="m",])

boxplot(gluc_Conc~Family,data=dat2[dat2$treatment=="gm",])

#bodymass
boxplot(GM_TotalLeaf_Area~Family,data=dat2[dat2$treatment=="a",])

boxplot(GM_TotalLeaf_Area~Family,data=dat2[dat2$treatment=="m",])

boxplot(GM_TotalLeaf_Area~Family,data=dat2[dat2$treatment=="gm",])

#Modelling: What influences performance (total leaf area)
#With limited dataset containing flavonoid data
summary(lmer(GM_TotalLeaf_Area ~ treatment*gluc_Conc+Fern+BlackPathDam +flav_Conc + (1 | gh_bench/gh_col) ,data=dat2))
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: GM_TotalLeaf_Area ~ treatment * gluc_Conc + Fern + BlackPathDam +
flav_Conc + (1 | gh_bench/gh_col)
Data: dat2
REML criterion at convergence: 6388.9
Scaled residuals:
Min 1Q Median 3Q Max
-3.2860 -0.5799 0.0639 0.5879 2.8024
Random effects:
Groups Name Variance Std.Dev.
gh_col:gh_bench (Intercept) 588144 766.9
gh_bench (Intercept) 1927899 1388.5
Residual 7116930 2667.8
Number of obs: 349, groups: gh_col:gh_bench, 28; gh_bench, 5
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 11705.91 2415.48 231.10 4.846 2.31e-06 ***
treatmentgm -8139.74 2860.71 322.70 -2.845 0.004720 **
treatmentm -8725.71 3156.29 328.21 -2.765 0.006022 **
gluc_Conc -4183.45 2377.16 322.41 -1.760 0.079381 .
Fern -122.68 56.51 330.47 -2.171 0.030631 *
BlackPathDam -162.81 41.42 328.48 -3.931 0.000103 ***
flav_Conc 2524.64 1213.99 338.49 2.080 0.038312 *
treatmentgm:gluc_Conc 4230.28 2889.49 321.40 1.464 0.144165
treatmentm:gluc_Conc 7832.59 3279.65 328.95 2.388 0.017493 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) trtmntg trtmntm glc_Cn Fern BlckPD flv_Cn trtmntg:_C
treatmentgm -0.767
treatmentm -0.697 0.588
gluc_Conc -0.856 0.736 0.675
Fern -0.001 -0.009 -0.055 -0.032
BlackPathDm -0.019 0.093 0.046 -0.053 -0.078
flav_Conc -0.179 0.084 0.071 -0.269 0.049 0.102
trtmntgm:_C 0.751 -0.991 -0.577 -0.737 0.002 -0.094 -0.063
trtmntm:g_C 0.669 -0.564 -0.993 -0.655 0.047 -0.042 -0.069 0.559
#Model Diagnostics.

#Visualization – The conditional benefit of glucosinolates (allelopathy)
aloneSlope<-function(x){
y=-3966.60*x+ 13751.96
return(y)
}
mapleSlope<-function(x){
y=(-4254.2+8417.95)*x+13751.96 -9243.71
return(y)
}
mustardSlope<-function(x){
y=+13751.96-8376.67#Non significant slope
return(y)
}
minM<-min(dat2$gluc_Conc[dat2$treatment=="m"],na.rm = T)
maxM<-max(dat2$gluc_Conc[dat2$treatment=="m"],na.rm = T)
minA<-min(dat2$gluc_Conc[dat2$treatment=="a"],na.rm = T)
maxA<-max(dat2$gluc_Conc[dat2$treatment=="a"],na.rm = T)
minG<-min(dat2$gluc_Conc[dat2$treatment=="gm"],na.rm = T)
maxG<-max(dat2$gluc_Conc[dat2$treatment=="gm"],na.rm = T)
#tiff("Selection_Figures/Gluc_Benefit.tiff", units="in", width=10, height=6, res=300)
library(ggplot2)
ggplot(dat2)+
geom_point(aes(y=GM_TotalLeaf_Area,x=gluc_Conc,colour=treatment),size=2)+
geom_segment(x=minA,xend=maxA,y=aloneSlope(minA),yend=aloneSlope(maxA),colour="#009E73",size=1.5)+
geom_segment(x=minM,xend=maxM,y=mapleSlope(minM),yend=mapleSlope(maxM),colour="#E69F00",size=1.5)+
geom_segment(x=minG,xend=maxG,y=mustardSlope(minG),yend=mustardSlope(maxG),colour="#56B4E9",size=1.5)+theme_simple()+
ylab(bquote(bold("Performance\n(Total Leaf Area "~(mm^2)~")")))+xlab(bquote(bold("[Total Glucosinolate] " (mg/ml))))+
scale_colour_manual(values=c("#009E73","#56B4E9","#E69F00"),labels=c("Alone","Garlic Mustard","Maple"))

#dev.off()
minA
[1] 0.7713421
#Visualizing the effect of flavonoid on fitness.
summary(lmer(GM_TotalLeaf_Area~treatment+flav_Conc+BlackPathDam+Fern+(1|Family)+(1|gh_bench/gh_col), data=dat2))
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: GM_TotalLeaf_Area ~ treatment + flav_Conc + BlackPathDam + Fern +
(1 | Family) + (1 | gh_bench/gh_col)
Data: dat2
REML criterion at convergence: 6473.8
Scaled residuals:
Min 1Q Median 3Q Max
-3.1990 -0.6278 0.0560 0.6004 2.6495
Random effects:
Groups Name Variance Std.Dev.
gh_col:gh_bench (Intercept) 660632 812.8
Family (Intercept) 210327 458.6
gh_bench (Intercept) 1767108 1329.3
Residual 7165525 2676.8
Number of obs: 350, groups: gh_col:gh_bench, 28; Family, 23; gh_bench, 5
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 7682.44 1156.80 33.30 6.641 1.42e-07 ***
treatmentgm -3897.18 385.80 333.76 -10.102 < 2e-16 ***
treatmentm -1133.35 364.02 330.79 -3.113 0.00201 **
flav_Conc 2471.19 1040.31 341.75 2.375 0.01808 *
BlackPathDam -77.69 30.19 335.79 -2.573 0.01050 *
Fern -125.75 57.56 330.33 -2.185 0.02962 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) trtmntg trtmntm flv_Cn BlckPD
treatmentgm -0.294
treatmentm -0.260 0.475
flav_Conc -0.795 0.198 0.137
BlackPathDm -0.163 -0.043 0.021 0.090
Fern -0.035 -0.037 -0.073 0.030 -0.156
aloneSlope<-function(x){
y=2024.62 *x+ 8035.30
return(y)
}
mapleSlope<-function(x){
y=(2024.62 )*x+ 8035.30 -1067.02
return(y)
}
mustardSlope<-function(x){
y=2024.62 *x+ 8035.30-3746.91#Non significant slope
return(y)
}
minM<-min(dat2$flav_Conc[dat2$treatment=="m"],na.rm = T)
maxM<-max(dat2$flav_Conc[dat2$treatment=="m"],na.rm = T)
minA<-min(dat2$flav_Conc[dat2$treatment=="a"],na.rm = T)
maxA<-max(dat2$flav_Conc[dat2$treatment=="a"],na.rm = T)
minG<-min(dat2$flav_Conc[dat2$treatment=="gm"],na.rm = T)
maxG<-max(dat2$flav_Conc[dat2$treatment=="gm"],na.rm = T)
#tiff("Selection_Figures/Flav_Benefit.tiff", units="in", width=10, height=6, res=300)
ggplot(dat2)+
geom_point(aes(y=GM_TotalLeaf_Area,x=flav_Conc,colour=treatment),size=2)+
geom_segment(x=minA,xend=maxA,y=aloneSlope(minA),yend=aloneSlope(maxA),colour="#009E73",size=1.5)+
geom_segment(x=minM,xend=maxM,y=mapleSlope(minM),yend=mapleSlope(maxM),colour="#E69F00",size=1.5)+theme_simple()+
geom_segment(x=minG,xend=maxG,y=mustardSlope(minG),yend=mustardSlope(maxG),colour="#56B4E9",size=1.5)+theme_simple()+
ylab(bquote(bold("Performance\n(Total Leaf Area "~(mm^2)~")")))+xlab(bquote(bold("[Total Flavonoid] " (mg/ml))))+
scale_colour_manual(values=c("#009E73","#56B4E9","#E69F00"),labels=c("Alone","Garlic Mustard","Maple"))

#dev.off()
#Visualization– The Detriment of pathogens and ferns
summary(lmer(GM_TotalLeaf_Area ~ Fern+
(1 | Family) + (1 | gh_bench/gh_col) ,data=dat2))
boundary (singular) fit: see ?isSingular
Linear mixed model fit by REML. t-tests use Satterthwaite's method [
lmerModLmerTest]
Formula: GM_TotalLeaf_Area ~ Fern + (1 | Family) + (1 | gh_bench/gh_col)
Data: dat2
REML criterion at convergence: 9607.6
Scaled residuals:
Min 1Q Median 3Q Max
-2.85397 -0.70508 0.04291 0.74619 3.11787
Random effects:
Groups Name Variance Std.Dev.
gh_col:gh_bench (Intercept) 96624 310.8
Family (Intercept) 0 0.0
gh_bench (Intercept) 2947085 1716.7
Residual 10094168 3177.1
Number of obs: 507, groups: gh_col:gh_bench, 28; Family, 23; gh_bench, 5
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 7896.911 807.136 4.071 9.784 0.000561 ***
Fern -226.020 56.097 432.082 -4.029 6.61e-05 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr)
Fern -0.055
convergence code: 0
boundary (singular) fit: see ?isSingular
a<-ggplot(dat2)+
geom_point(aes(y=GM_TotalLeaf_Area,x=BlackPathDam))+theme_simple_multiCol()+
geom_abline(intercept=8281.76,slope = -105.28,size=1.5)+
xlab("Black Pathogen Damage")
b<-ggplot(dat2[dat2$WhiteFungDam<30,])+
geom_point(aes(y=GM_TotalLeaf_Area,x=WhiteFungDam),colour="#999999")+theme_simple_multiCol()+
theme(axis.title.x = element_text(color = "#999999", size = 16, face = "bold",margin=margin(3,0,3,0)),
)+xlab("Powdery Mildew Damage")
c<-ggplot(dat2)+
geom_point(aes(y=GM_TotalLeaf_Area,x=ThripsDam),colour="#E69F00")+theme_simple_multiCol()+xlab("Thrips Damage")+
theme(axis.title.x = element_text(color = "#E69F00", size = 16, face = "bold",margin=margin(3,0,3,0)))
d<-ggplot(dat2)+
geom_point(aes(y=GM_TotalLeaf_Area,x=Fern),colour="#009E73")+theme_simple_multiCol()+xlab("Fern Abundance")+
geom_abline(intercept=8003.44,slope = -179.47,size=1.5,color="#009E73")+
theme(axis.title.x = element_text(color = "#009E73", size = 16, face = "bold",margin=margin(3,0,3,0)))
plot<-plot_grid(a, b,ncol=2,rel_widths = c(1,1))
Removed 61 rows containing missing values (geom_point).Removed 61 rows containing missing values (geom_point).
plot2<-plot_grid(d, c,ncol=2,rel_widths = c(1,1))
Removed 9 rows containing missing values (geom_point).Removed 61 rows containing missing values (geom_point).
plot3<-plot_grid(a,b,c,d,ncol=2,rel_widths = c(1,1))
Removed 61 rows containing missing values (geom_point).Removed 61 rows containing missing values (geom_point).Removed 61 rows containing missing values (geom_point).Removed 9 rows containing missing values (geom_point).
plot4<-plot_grid(a,b,c,ncol=1,rel_widths = c(1,1,1))
Removed 61 rows containing missing values (geom_point).Removed 61 rows containing missing values (geom_point).Removed 61 rows containing missing values (geom_point).
plot5<-plot_grid(a,b,c,ncol=3,rel_widths = c(1,1,1))
Removed 61 rows containing missing values (geom_point).Removed 61 rows containing missing values (geom_point).Removed 61 rows containing missing values (geom_point).
y.grob<-textGrob(bquote(bold("Shoot Area "(mm^2))),gp=gpar(fontface="bold",fontsize=20),rot=90)
#tiff("Selection_Figures/PathogenEffect.tiff", units="in", width=14, height=6, res=300)
grid.arrange(plot,left=y.grob)

#dev.off()
#tiff("Selection_Figures/PathogenEffect2.tiff", units="in", width=14, height=6, res=300)
grid.arrange(plot2,left=y.grob)

#dev.off()
#tiff("Selection_Figures/PathogenEffect3.tiff", units="in", width=14, height=10, res=300)
grid.arrange(plot3,left=y.grob)

#dev.off
grid.arrange(plot4,left=y.grob)

#tiff("Selection_Figures/PathogenEffect5.tiff", units="in", width=16, height=5, res=300)
grid.arrange(plot5,left=y.grob)

#dev.off
#tiff("Selection_Figures/FernEffect.tiff", units="in", width=8, height=6, res=300)
grid.arrange(d,left=y.grob)

#dev.off
#—————————————– #Part 2
#Influence of gluc and flav on defence.
hist(dat$ThripsDam)
Warning messages:
1: Unknown or uninitialised column: `WhiteFungLogis`.
2: Unknown or uninitialised column: `WhiteFungLogis`.

#Significant testing
#WhitePathDam – logistic regression
#Because of how zero inflated white pathogen damage is, i will use a logistic regression to model it.
dat2$WhiteFungLogis<-NA
dat2$WhiteFungLogis[dat2$WhiteFungDam==0]<-0
dat2$WhiteFungLogis[dat2$WhiteFungDam>0]<-1
#This is the biggest model that could converge. ... interaction with flavonoid could not.
fit_full_g<-glmer(WhiteFungLogis~treatment*gluc_Conc+flav_Conc+(1|Family),family=binomial,data=dat2[!is.na(dat2$flav_Conc),])
fit.1<-update(fit_full_g,~.-flav_Conc)
anova(fit_full_g,fit.1) #Flavonoid Concentration is not significant.
Data: dat2[!is.na(dat2$flav_Conc), ]
Models:
fit.1: WhiteFungLogis ~ treatment + gluc_Conc + (1 | Family) + treatment:gluc_Conc
fit_full_g: WhiteFungLogis ~ treatment * gluc_Conc + flav_Conc + (1 | Family)
npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
fit.1 7 402.61 429.62 -194.31 388.61
fit_full_g 8 403.89 434.76 -193.95 387.89 0.7204 1 0.396
#Testing glucosinolate treatment interaction.
fit.2<-glmer(WhiteFungLogis~treatment*gluc_Conc+(1|Family),family=binomial,data=dat2)
Model failed to converge with max|grad| = 0.00272048 (tol = 0.002, component 1)
fit.3<-glmer(WhiteFungLogis~treatment+gluc_Conc+(1|Family),family=binomial,data=dat2)
anova(fit.2,fit.3) #Glucosinolate:Treatment interaction is not significant.
Data: dat2
Models:
fit.3: WhiteFungLogis ~ treatment + gluc_Conc + (1 | Family)
fit.2: WhiteFungLogis ~ treatment * gluc_Conc + (1 | Family)
npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
fit.3 5 416.98 436.48 -203.49 406.98
fit.2 7 416.63 443.93 -201.32 402.63 4.3439 2 0.114
#Testing glucosinolate involvment at all.
fit.4<-glmer(WhiteFungLogis~treatment+(1|Family),family=binomial,data=dat2[!is.na(dat2$gluc_Conc),])
fit.3<-glmer(WhiteFungLogis~treatment+gluc_Conc+(1|Family),family=binomial,data=dat2[!is.na(dat2$gluc_Conc),])
anova(fit.4,fit.3) #Glucosinolate Concentration is not a significant predictor
Data: dat2[!is.na(dat2$gluc_Conc), ]
Models:
fit.4: WhiteFungLogis ~ treatment + (1 | Family)
fit.3: WhiteFungLogis ~ treatment + gluc_Conc + (1 | Family)
npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
fit.4 4 415.04 430.64 -203.52 407.04
fit.3 5 416.98 436.48 -203.49 406.98 0.0644 1 0.7997
#Testing effect of treatment
fit.4<-glmer(WhiteFungLogis~treatment+(1|Family),family=binomial,data=dat2)
fit.5<-glmer(WhiteFungLogis~1+(1|Family),family=binomial,data=dat2)
anova(fit.4,fit.5)
Data: dat2
Models:
fit.5: WhiteFungLogis ~ 1 + (1 | Family)
fit.4: WhiteFungLogis ~ treatment + (1 | Family)
npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
fit.5 2 523.93 532.17 -259.97 519.93
fit.4 4 519.23 535.71 -255.62 511.23 8.7022 2 0.01289 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#treatment is significant......
summary(fit.4) #Garlic mustard in the maple treatment have less occurence of fungal colonization.
Generalized linear mixed model fit by maximum likelihood (Laplace
Approximation) [glmerMod]
Family: binomial ( logit )
Formula: WhiteFungLogis ~ treatment + (1 | Family)
Data: dat2
AIC BIC logLik deviance df.resid
519.2 535.7 -255.6 511.2 451
Scaled residuals:
Min 1Q Median 3Q Max
-1.3885 -0.6239 -0.4587 0.9947 3.3329
Random effects:
Groups Name Variance Std.Dev.
Family (Intercept) 0.544 0.7376
Number of obs: 455, groups: Family, 23
Fixed effects:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.6835 0.2395 -2.854 0.00431 **
treatmentgm -0.4101 0.2613 -1.569 0.11656
treatmentm -0.8037 0.2756 -2.916 0.00355 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) trtmntg
treatmentgm -0.509
treatmentm -0.474 0.447
plot(fit.4)

#Visualizing – effect of treatment on proportion of fungal abundance.
#Summarizing for Display: generating frequency of white funal infection by treatment
plot<-dat2 %>% drop_na(WhiteFungLogis) %>% group_by(treatment) %>% summarize(PercWhitFung=sum(WhiteFungLogis)/length(WhiteFungLogis)*100)
#tiff("Defence_Figures/TreatMeanWhiteFung.tiff", units="in", width=8, height=5, res=300)
ggplot(plot)+
geom_col(aes(x=treatment,y=PercWhitFung,fill=treatment))+theme_simple()+ylab("Fungal Abundance\n (% Infected)")+
scale_y_continuous(breaks = seq(0,30,5))+
scale_x_discrete(name="",labels=c("Alone","Garlic Mustard","Maple"))+
scale_fill_manual(values=c("#009E73","#56B4E9","#E69F00"),labels=c("Alone","Garlic Mustard","Maple"))+
theme_simple_multiCol()+theme(axis.title.y = element_text(color = "black", size = 16, face = "bold",margin=margin(3,20,3,0)))

#dev.off()
#BlackPathDam – logistic regression– (redo new data)
dat$BlackPathDam==0
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[12] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[23] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[34] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[45] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[56] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[67] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[78] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[89] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[100] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[111] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[122] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[133] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[144] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[155] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[166] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[177] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[188] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[199] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[210] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[221] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[232] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[243] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[254] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[265] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[276] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[287] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[298] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[309] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[320] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[331] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[342] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[353] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[364] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[375] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[386] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[397] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[408] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[419] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[430] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[441] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[452] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[463] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[474] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[485] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[496] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[507] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[518] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[529] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[540] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[551] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[562] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[573] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[584] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[595] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[606] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[617] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[628] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[639] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[650] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[661] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[672] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[683] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[694] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[705] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[716] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[727] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[738] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[749] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[760] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[771] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[782] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[793] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[804] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[815] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[826] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[837] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[848] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[859] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[870] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE NA NA NA
[881] NA NA NA NA NA NA NA NA NA NA NA
[892] NA NA NA NA NA NA NA NA NA NA NA
[903] NA NA NA NA NA NA NA NA NA NA NA
[914] NA NA NA NA NA NA NA NA NA NA NA
[925] NA NA NA NA NA NA FALSE NA NA NA NA
[936] FALSE FALSE NA NA NA NA FALSE FALSE FALSE FALSE FALSE
[947] NA FALSE FALSE NA NA NA NA NA NA NA NA
[958] FALSE FALSE NA FALSE NA NA NA
Warning messages:
1: Unknown or uninitialised column: `WhiteFungLogis`.
2: Unknown or uninitialised column: `WhiteFungLogis`.
#Visualizing — the distribution of pathogens by treatment.
plot2<-dat2 %>% drop_na(BlackPathDam) %>% group_by(treatment) %>% summarize(BlackPathAve=mean(BlackPathDam,na.rm=T))
plot3<-dat2 %>% drop_na(ThripsDam) %>% group_by(treatment) %>% summarize(ThripsDam=mean(ThripsDam,na.rm=T))
plot4<-dat2 %>% drop_na(Fern) %>% group_by(treatment) %>% summarize(Fern=mean(Fern,na.rm=T))
#Black Pathogen abundance by treamtent
ggplot(plot2)+
geom_col(aes(x=treatment,y=BlackPathAve,fill=treatment))+theme_simple()+ylab("Fungal Abundance\n (% colonized)")+xlab("Treatment")+theme(legend.position = "none")

#Thrips abundance by treatment.
ggplot(plot3)+
geom_col(aes(x=treatment,y=ThripsDam,fill=treatment))+theme_simple()+ylab("Fungal Abundance\n (% colonized)")+xlab("Treatment")+theme(legend.position = "none")

#I would need to account for the garlic mustard being psuedoreplicated iwth the fern data, because each gm in the gm treatment was grown with another gm in the same pot.
ggplot(plot4)+
geom_col(aes(x=treatment,y=Fern,fill=treatment))+theme_simple()+ylab("Average Fern Abundance (#Ferns/pot)")+xlab("Treatment")+theme(legend.position = "none")+
scale_x_discrete(name="",labels=c("Alone","Garlic Mustard","Maple"))+
scale_fill_manual(values=c("#009E73","#56B4E9","#E69F00"),labels=c("Alone","Garlic Mustard","Maple"))+
theme_simple_multiCol()+theme(axis.title.y = element_text(color = "black", size = 16, face = "bold",margin=margin(3,20,3,0)))

#dev.off()
#Modelling – Poisson -What influences White pathogen damage?
#the inclusion of GH_Bench does not affect the outcome of the model, thereofre, I am excluding it as the other model was saturated and took alot time to compute.
summary(glmer(WhiteFungDam~treatment+gluc_Conc+(1|Family/Tag),family=poisson,data=dat))
Generalized linear mixed model fit by maximum likelihood (Laplace
Approximation) [glmerMod]
Family: poisson ( log )
Formula: WhiteFungDam ~ treatment + gluc_Conc + (1 | Family/Tag)
Data: dat
AIC BIC logLik deviance df.resid
1031.7 1059.1 -509.9 1019.7 698
Scaled residuals:
Min 1Q Median 3Q Max
-2.0689 -0.2816 -0.2273 -0.1792 2.4492
Random effects:
Groups Name Variance Std.Dev.
Tag:Family (Intercept) 3.5609 1.8870
Family (Intercept) 0.1535 0.3918
Number of obs: 704, groups: Tag:Family, 433; Family, 23
Fixed effects:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -0.19135 0.74206 -0.258 0.79651
treatmentgm 0.03379 0.33152 0.102 0.91882
treatmentm -0.81257 0.35173 -2.310 0.02088 *
gluc_Conc -2.32108 0.71157 -3.262 0.00111 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) trtmntg trtmntm
treatmentgm -0.306
treatmentm -0.341 0.484
gluc_Conc -0.907 0.126 0.175
Warning messages:
1: Unknown or uninitialised column: `WhiteFungLogis`.
2: Unknown or uninitialised column: `WhiteFungLogis`.
3: Unknown or uninitialised column: `WhiteFungLogis`.
4: Unknown or uninitialised column: `WhiteFungLogis`.
5: Unknown or uninitialised column: `WhiteFungLogis`.
6: Unknown or uninitialised column: `WhiteFungLogis`.
#Visuallizing – white fungal damage is influenced by gluc and treatmnet.
PoisSlope=function(x,int){
y=exp(-2.32292*x+int)
return(y)
}
glucplot=seq(min(dat$gluc_Conc),max(dat$gluc_Conc),length.out = 695)
FungA<-PoisSlope(glucplot,-0.15701)
FungM<-PoisSlope(glucplot,-0.15701-0.82060)
FungGM<-PoisSlope(glucplot,-0.15701+0.02483)
fit.g<-glm(WhiteFungDam~gluc_Conc+treatment,family=poisson,data=dat)
summary(fit.g)
predict(fit.g,type="response",newdata=data.frame("treatment"=rep("a",695),"gluc_Conc"=glucplot))
datv<-dat[!is.na(dat$WhiteFungDam),]
#tiff("Defence_Figures/GlucosinolateFungi.tiff", units="in", width=10, height=6, res=300)
ggplot(datv[datv$WhiteFungDam<30,])+
geom_point(aes(y=WhiteFungDam,x=gluc_Conc,colour=treatment))+
scale_colour_manual(values=c("#009E73","#56B4E9","#E69F00","#009E73","#56B4E9","#E69F00"),labels=c("Alone","Garlic Mustard","Maple"))+theme_simple()+
scale_y_continuous(breaks=c(0,2,4,6,8,10,12))+
geom_path(x=glucplot,y=FungA,colour="#009E73")+
geom_path(x=glucplot,y=FungM,colour="#E69F00")+
ylab("Powdery Mildew Damage")+
xlab(bquote(bold("[Total Glucosinolate] " (mg/ml))))
#dev.off()
#Modelling – What influences Black Pathogen Damage? –(redo new data)
sum(newframe$gluc_Conc>=3.605 ,na.rm = T)/length(newframe$gluc_Conc)
[1] 0.06040268
#Visuallizing – Black Pathogen damage is influenced by flavonoids.
PoisSlope=function(x){
y=exp(-1.1150*x+1.6816)
return(y)
}
flavplot=seq(min(dat$flav_Conc,na.rm = T),max(dat$flav_Conc,na.rm=T),length.out = 687)
flavy<-PoisSlope(flavplot)
#tiff("Defence_Figures/FlavonoidBlackPath.tiff", units="in", width=10, height=6, res=300)
ggplot(dat[!is.na(dat$flav_Conc)&!is.na(dat$flav_Conc),])+
geom_point(aes(y=BlackPathDam,x=flav_Conc))+theme_simple()+
geom_path(x=flavplot,y=flavy,size=1,colour="#999999")+
scale_y_continuous(breaks=c(0,5,10,15,20,25,30))+
ylab("Black Pathogen Damage")+
xlab(bquote(bold("[Total Flavonoid] " (mg/ml))))
#dev.off()
#What influences Thrips damage? –(redo new data)
plot(fit.4)
Warning messages:
1: Unknown or uninitialised column: `WhiteFungLogis`.
2: Unknown or uninitialised column: `WhiteFungLogis`.

#Visualizing - influence of flavonoids on thrips damage.
PoisSlope=function(x){
y=exp(-2.3319*x+3.5249)
return(y)
}
flavplot=seq(min(dat$flav_Conc,na.rm = T),max(dat$flav_Conc,na.rm=T),length.out = 687)
flavy<-PoisSlope(flavplot)
#tiff("Defence_Figures/FlavonoidThrips.tiff", units="in", width=10, height=6, res=300)
ggplot(dat[!is.na(dat$flav_Conc)&!is.na(dat$flav_Conc),])+
geom_point(aes(y=ThripsDam,x=flav_Conc))+theme_simple()+
geom_path(x=flavplot,y=flavy,size=1,colour="#999999")+
scale_y_continuous(breaks=c(0,5,10,15,20,25,30,35,40))+
ylab("Thrips Damage")+
xlab(bquote(bold("[Total Flavonoid] " (mg/ml))))
#dev.off()
#Visualizing – effect of flavonoids on fern abundance.
PoisSlope=function(x,int){
y=exp((-0.02353 -3.12475)*x+int)
return(y)
}
exp(-0.6571)
flavplot=seq(min(dat$flav_Conc,na.rm = T),max(dat$flav_Conc,na.rm=T),length.out = 707)
flavyA<-PoisSlope(flavplot,-2.1683)
flavyM<-PoisSlope(flavplot,-1.60546-2.81450)
flavyGM<-PoisSlope(flavplot,-2.1683-0.2786)
#tiff("Defence_Figures/FlavonoidFern.tiff", units="in", width=10, height=6, res=300)
ggplot(dat)+
geom_point(aes(y=Fern,x=flav_Conc,colour=treatment))+theme_simple()+
# geom_path(x=flavplot,y=flavyA,size=1,colour="#009E73")
#geom_path(x=flavplot,y=flavyGM,size=1,colour="#56B4E9")
geom_path(x=flavplot,y=flavyM,size=1,colour="#E69F00")+
scale_colour_manual(values=c("#009E73","#56B4E9","#E69F00"),labels=c("Alone","Garlic Mustard","Maple"))+
scale_y_continuous(breaks=c(0,5,10,15,20,25,30,35,40))+
ylab("Fern Abundance")+
xlab(bquote(bold("[Total Flavonoid] " (mg/ml))))
#dev.off()
How can we know that healthy plants dont just exhibit more secondary compounds and not that those with more secondary compounds are healthier?
LS0tCnRpdGxlOiAiU2VsZWN0aXZlIGJlbmVmaXQgb2YgR2x1Y29zaW5vbGF0ZSBhbmQgZmxhdm9ub2lkcyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQojUGFydCAxClRoZSBwdXJwb3NlIG9mIHRoaXMgbm90ZWJvb2sgaXMgdG8gZGV0ZXJtaW5lIHRoZSBzZWxlY3RpdmUgYmVuZWZpdCBvZiBnbHVjb3Npbm9sYXRlIGFuZCBmbGF2b25vaWQgY29tcG91bmRzIHRocm91Z2ggcGxhbnQgY29tcGV0aXRpb24gYnkgY3JlYXRpbmcgc2VsZWN0aW9uIGdyYWRpZW50cy4gU2VsZWN0aW9uIGdyYWRpZW50cyB3aWxsIGludm9sdmUgZmluYWwgYm9keSBtYXNzIGFzIHRoZSBwcm94eSBmb3IgZml0bmVzcywgYnV0IHRoaXMgd2lsbCBiZSByZXBsYWNlZCB3aXRoIGZpdG5lc3Mgb25jZSB0aGUgbWVhc3VyZW1lbnQgaXMgaW4uIENvbmNlbnRyYXRpb24gd2lsbCBiZSBvbiB0aGUgeC1heGlzLiBUaGlzIGFuYWx5c2lzIHdpbGwgYWNjb3VudCBmb3IgZmFtaWx5IGFuZCBncmVlbmhvdXNlIGxvY2F0aW9uLiAKCiNQYXJ0IDIKVGhlIHNlY29uZCBwdXJwb3NlIGlzIHRvIGRldGVybWluZSBpZiBnbHVjb3Npbm9sYXRlcyBhbmQgZmxhdm9ub2lkcyBpbmZsdWVuY2Ugc3VzY3BldGliaWxpdHkgdG8gcGF0aG9nZW5zIGFuZCBpZiB0aGlzIHN1c2NlcHRpYmlsaXR5IHJlc3VsdHMgaW4gaW5jcmVhc2VkIGZpdG5lc3MKCgoKCiNSZWFkIGluIGFuZCBwcmVwIGRhdGEKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShsbWU0KQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkoZ3JpZCkKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkoZHBseXIpCnNvdXJjZSgiR0dQbG90X1RoZW1lcy5SIikKCiNyZWFkIGluIGRhdGEKcm0obGlzdD1scygpKQpkYXQ8LXJlYWQuY3N2KCJEYXRhU3ludGhlc2lzLmNzdiIpCgojUmVtb3ZlIG1hcGxlIGNvbnRyb2xzIGRhdGEgZnJvbSB0aGUgZGF0YSBzZXQuCmRhdDwtZGF0ICU+JSBmaWx0ZXIodHJlYXRtZW50IT0ibWNudCIpICU+JSBkcm9wbGV2ZWxzKCkKCiNBc3NpZ24gZmFtaWx5IGNvbHVtbgpwcmVmYW1pbHk8LWdzdWIoIiouXFx8IiwiIixkYXQkVGFnKQpkYXQkRmFtaWx5PC1nc3ViKCJcXC0uKiIsIiIscHJlZmFtaWx5KQoKI3JlbW92ZSB0aG9zZSB3aXRoIGZlcnRpbGl6ZXIgdHJlYXRtZW50LCBhbmQgZXh0cmEgZ2Vub3R5cGVzIHRoYXQgYXJlIG9ubHkgaW4gdGhlIGFsb25lIHRyZWF0bWVudC4gCmRhdDwtZGF0WyFncmVwbCgiaSIsZGF0JFNhbXBsZSxmaXhlZD1UKSxdCgojSW5pdGlhbGl6aW5nIGNvbHVtbnMgdG8gYXZvaWQgY29uc3RhbnQgZXJyb3IgbWVzc2FnZXMuIApkYXQkV2hpdGVGdW5nTG9naXM8LU5BCmRhdCRCbGFja0Z1bmdMb2dpczwtTkEKYGBgCgoKI0dlbmVyYXRpbmcgZGF0YSBmcmFtZXMgd2l0aCBzdW1tYXJpemVkIGxlYWYgZGF0YSAoZGF0MikgYW5kIHN1bW1hcml6ZWQgZ2Vub3R5cGUgZGF0YSAoZGF0MykKYGBge3J9CiNTdW1tYXJpemluZzogVGFraW5nIHRoZSBtZWFuIHZhbHVlIG9mIGxlYXZlcy4gVGhpcyB0aWJibGUgY29udGFpbnMgZGF0YSBhdCB0aGUgbGV2ZWwgb2YgdGhlIHBsYW50IG1lYW5zLiAKZGF0MjwtZGF0ICU+JSBncm91cF9ieShUYWcpICU+JSBzdW1tYXJpemUoQ2hsb3JBPW1lYW4oQ2hsb3JBKSxDaGxvckI9bWVhbihDaGxvckIpLGdsdWNfQ29uYz1tZWFuKGdsdWNfQ29uYyksZmxhdl9Db25jPW1lYW4oZmxhdl9Db25jKSxGYW1pbHk9Zmlyc3QoRmFtaWx5KSx0cmVhdG1lbnQ9Zmlyc3QodHJlYXRtZW50KSxnaF9yb3c9Zmlyc3QoZ2hfcm93KSxnaF9iZW5jaD1maXJzdChnaF9iZW5jaCksR01fVG90YWxMZWFmX0FyZWE9Zmlyc3QoR01fVG90YWxMZWFmX0FyZWEpLGNvbXBfbnVtYmVyPWZpcnN0KGNvbXBfbnVtYmVyKSxUaHJpcHNEYW09bWVhbihUaHJpcHNEYW0pLFdoaXRlRnVuZ0RhbT1tZWFuKFdoaXRlRnVuZ0RhbSksQmxhY2tQYXRoRGFtPW1lYW4oQmxhY2tQYXRoRGFtKSxGZXJuPW1lYW4oRmVybiksZ2hfY29sPWZpcnN0KGdoX2NvbCkpCmRhdAoKI0FsbCBvZiB0aGVzZSBnZW5vdHlwZXMgZGllZCAoMTUgR2Vub3R5cGVzKS4oV2UgYXJlIHNpbXBseSBtaXNzaW5nIGEgZmluYWwgbWVhc3VyZW1lbnQgZm9yIGV8SkJDSFkxLTEtNTB8UXwyNDApIFRoYXQgaXMgb25seSAzJSBNb3J0YWxpdHkuIApkZWFkPC1kYXQyW2lzLm5hKGRhdDIkR01fVG90YWxMZWFmX0FyZWEpLF0KCiNSZW1vdmluZyB0aG9zZSB3aXRoIGRlYWQgY29tcGV0aXRvcnMgZnJvbSB0aGUgZ2FybGljIG11c3RhcmQgdHJlYXRtZW50LiAoImV8SkJDSFkxLTEtNTB8UXwyNDAiKSBkaWQgbm90IGRpZSwgd2UgYXJlIHNpbXBseSBtaXNzaW5nIHRoZSBmaW5hbCBtZWFzdXJlbWVudCBmb3IgaXQuCgpkZWFkX2NvbXBldGl0b3JzPC1kZWFkICU+JSBmaWx0ZXIodHJlYXRtZW50PT0iZ20iLFRhZyE9ImV8SkJDSFkxLTEtNTB8UXwyNDAiKSAlPiUgc2VsZWN0KGNvbXBfbnVtYmVyKQoKI1JlbW92aW5nIHRob3NlIHdpdGggZGVhZCBjb21wZXRpdG9ycyBmcm9tIHRoZSBhbmFseXNpcy4gCmRhdDI8LWRhdDIgJT4lIGZpbHRlcighY29tcF9udW1iZXIgJWluJSBkZWFkX2NvbXBldGl0b3JzJGNvbXBfbnVtYmVyKQoKCiMjU3VtbWFyaXppbmc6IFRha2luZyB0aGUgbWVhbiB2YWx1ZSBvZiBwbGFudHMuIFRoaXMgdGliYmxlIGNvbnRhaW5zIGRhdGEgYXQgdGhlIGxldmVsIG9mIHRoZSBmYW1pbHkgbWVhbnMgd2l0aGluIGVhY2ggdHJlYXRtZW50LiAKZGF0MzwtZGF0MiAlPiUgZHJvcF9uYShHTV9Ub3RhbExlYWZfQXJlYSkgJT4lIGdyb3VwX2J5KEZhbWlseSx0cmVhdG1lbnQpICAlPiUgc3VtbWFyaXplX2lmKGlzLm51bWVyaWMsbWVhbikKCmBgYAoKCiNTZWFyY2hpbmcgZm9yIGEgZml0bmVzcyB0cmFkZS1vZmYgYmV0d2VlbiB0aGUgYWxvbmUgYW5kIGludGVyc3BlY2lmaWMgY29tcGV0aXRpb24gdHJlYXRtZW50LiAKYGBge3J9CnNvdXJjZSgiR0dQbG90X1RoZW1lcy5SIikKCiNDYWxjdWxhdGluZyBmYW1pbHkgbWVhbnMgd2l0aGluIHRyZWF0bWVudC4gClRyYWRlT2ZmPC1kYXQzICU+JSBmaWx0ZXIodHJlYXRtZW50PT0iYSIpICU+JSBkcm9wX25hKEdNX1RvdGFsTGVhZl9BcmVhKSAlPiUgIHNlbGVjdChMZWFmU2l6ZUFsb25lPUdNX1RvdGFsTGVhZl9BcmVhLEZhbWlseSxnbHVjX0NvbmNBbG9uZT1nbHVjX0NvbmMpICU+JSByaWdodF9qb2luKGRhdDMgJT4lIGZpbHRlcih0cmVhdG1lbnQ9PSJtIikgJT4lICBzZWxlY3QoTGVhZlNpemVNYXBsZT1HTV9Ub3RhbExlYWZfQXJlYSxGYW1pbHksZ2x1Y19Db25jTWFwbGU9Z2x1Y19Db25jKSxieT0iRmFtaWx5IikKCiNDYWxjdWxhdGluZyBzdGFuZGFyZCBlcnJvciBvZiBlYWNoIGZhbWlseQpTdGRFcnI8LWRhdDIgJT4lIHNlbGVjdChGYW1pbHksdHJlYXRtZW50LEdNX1RvdGFsTGVhZl9BcmVhKSAlPiUgZ3JvdXBfYnkoRmFtaWx5LHRyZWF0bWVudCkgJT4lIGRyb3BfbmEoR01fVG90YWxMZWFmX0FyZWEpICU+JSAgc3VtbWFyaXplKFN0ZEVycj1zZChHTV9Ub3RhbExlYWZfQXJlYSkvc3FydChsZW5ndGgoR01fVG90YWxMZWFmX0FyZWEpKSxzaXplPWxlbmd0aChHTV9Ub3RhbExlYWZfQXJlYSkpCgojU2hpZnRpbmcgdGhlIGRhdGEgdG8gYmUgaW4gbG9uZyBmb3JtLiAKU3RkRXJyMjwtU3RkRXJyICU+JSBmaWx0ZXIodHJlYXRtZW50PT0iYSIpICU+JSBzZWxlY3QoU3RkRXJyQWxvbmU9U3RkRXJyLEZhbWlseSkgJT4lIHJpZ2h0X2pvaW4oU3RkRXJyICU+JSBmaWx0ZXIodHJlYXRtZW50PT0ibSIpICU+JSBzZWxlY3QoU3RkRXJyTWFwbGU9U3RkRXJyLEZhbWlseSksYnk9IkZhbWlseSIpCgpUcmFkZU9mZjI8LVN0ZEVycjIgJT4lIGxlZnRfam9pbihUcmFkZU9mZikKCgojdGlmZigiU2VsZWN0aW9uX0ZpZ3VyZXMvVHJhZGVPZmYudGlmZiIsIHVuaXRzPSJpbiIsIHdpZHRoPTEwLCBoZWlnaHQ9NiwgcmVzPTMwMCkKCmdncGxvdChUcmFkZU9mZjIsYWVzKHk9TGVhZlNpemVBbG9uZSx4PUxlYWZTaXplTWFwbGUpKSsKICBnZW9tX3BvaW50KCkrCiAgZ2VvbV9saW5lcmFuZ2UoYWVzKHltaW4gPSBMZWFmU2l6ZUFsb25lIC0gU3RkRXJyQWxvbmUsIAogICAgICAgICAgICAgICAgICAgIHltYXggPSBMZWFmU2l6ZUFsb25lICsgU3RkRXJyQWxvbmUpKSsKICBnZW9tX2Vycm9yYmFyaChhZXMoeG1pbiA9IExlYWZTaXplTWFwbGUgLSBTdGRFcnJNYXBsZSwKICAgICAgICAgICAgICAgICAgICB4bWF4ID0gTGVhZlNpemVNYXBsZSArIFN0ZEVyck1hcGxlKSkrCnRoZW1lX3NpbXBsZSgpKwogIHhsYWIoIlBlcmZvcm1hbmNlIHdpdGggTWFwbGUiKSsKICB5bGFiKCJQZXJmb3JtYW5jZSBBbG9uZSIpCiNkZXYub2ZmKCkKc3VtbWFyeShsbShMZWFmU2l6ZUFsb25lfkxlYWZTaXplTWFwbGUsZGF0YT1UcmFkZU9mZjIpKQoKYGBgCgoKCgoKI1Zpc3VhbGl6aW5nIGdlbmV0aWMgdmFyaWF0aW9uIGFuZCBncmVlbmhvdXNlIHZhcmlhdGlvbiwgd2hpY2ggd2lsbCBiZSBjb250cm9sbGVkIGZvci4gCmBgYHtyfQojR0ggQmVuY2gKZ2dwbG90KGRhdDIpKwogIGdlb21fcG9pbnQoYWVzKHk9Z2x1Y19Db25jLHg9Z2hfYmVuY2gsY29sb3VyPWFzLmZhY3RvcihnaF9iZW5jaCkpKQoKI0dIIENvbApnZ3Bsb3QoZGF0MikrCiAgZ2VvbV9wb2ludChhZXMoeT1nbHVjX0NvbmMseD1naF9jb2wsY29sb3VyPWFzLmZhY3RvcihnaF9iZW5jaCkpKQoKI0ludmVzdGlnYXRpbmcgZ2VuZXRpYyBkaWZmZXJlbmNlcyBieSB0cmVhdG1lbnQKI2dsdWNfQ29uYwpib3hwbG90KGdsdWNfQ29uY35GYW1pbHksZGF0YT1kYXQyW2RhdDIkdHJlYXRtZW50PT0iYSIsXSkKYm94cGxvdChnbHVjX0NvbmN+RmFtaWx5LGRhdGE9ZGF0MltkYXQyJHRyZWF0bWVudD09Im0iLF0pCmJveHBsb3QoZ2x1Y19Db25jfkZhbWlseSxkYXRhPWRhdDJbZGF0MiR0cmVhdG1lbnQ9PSJnbSIsXSkKI2JvZHltYXNzCmJveHBsb3QoR01fVG90YWxMZWFmX0FyZWF+RmFtaWx5LGRhdGE9ZGF0MltkYXQyJHRyZWF0bWVudD09ImEiLF0pCmJveHBsb3QoR01fVG90YWxMZWFmX0FyZWF+RmFtaWx5LGRhdGE9ZGF0MltkYXQyJHRyZWF0bWVudD09Im0iLF0pCmJveHBsb3QoR01fVG90YWxMZWFmX0FyZWF+RmFtaWx5LGRhdGE9ZGF0MltkYXQyJHRyZWF0bWVudD09ImdtIixdKQpgYGAKCgoKI01vZGVsbGluZzogV2hhdCBpbmZsdWVuY2VzIHBlcmZvcm1hbmNlICh0b3RhbCBsZWFmIGFyZWEpCmBgYHtyfQojVGhpcyBpcyB0aGUgZnVsbCBtb2RlbC5JIGV4cGVjdCB0aGF0IHRoZSBpbmZsdWVuY2Ugb2YgZ2x1YyBjb25jIGFuZCBmbGF2IGNvbmMgY291bGQgdmFyeSBiZXR3ZWVuIHRyZWF0bWVudHMgYmVjYXVzZSBvZiBhbGxlbG9wYXRoeSwgdGhlcmVmb3JlLCBpIGluY2x1ZGUgaW50ZXJhY3Rpb25zIHdpdGggdGhlc2UgdmFyaWFibGVzLiBIb3dldmVyLCBpIGhhdmUgbm8gcmVhc29uIHRvIHRoaW5rIHRoYXQgcGF0aG9nZW5zIG9yIGZlcm4gYWJ1bmRhbmNlIGNvdWxkIGluZmx1ZW5jZSBmaXRuZXNzIGRpZmZlcmVudGx5IGluIGRpZmZlcmVudCB0cmVhdG1lbnRzLCB0aGVyZWZvcmUsIG5vIGludGVyYWN0aW9ucyBhcmUgaW5jbHVkZWQuCgojRmlyc3QgbGV0cyBlbnN1cmUgd2UgYXJlIHVzaW5nIHRoZSBjb3JyZWN0IHJhbmRvbSBlZmZlY3RzLgoKCmZpdGZ1bGw8LWxtZXIoR01fVG90YWxMZWFmX0FyZWF+dHJlYXRtZW50KmdsdWNfQ29uYypmbGF2X0NvbmMrQmxhY2tQYXRoRGFtK1doaXRlRnVuZ0RhbStUaHJpcHNEYW0rRmVybisoMXxGYW1pbHkpKygxfGdoX2JlbmNoL2doX3JvdyksIGRhdGE9ZGF0MikKCmZpdGZ1bGwyPC1sbWVyKEdNX1RvdGFsTGVhZl9BcmVhfnRyZWF0bWVudCpnbHVjX0NvbmMqZmxhdl9Db25jK0JsYWNrUGF0aERhbStXaGl0ZUZ1bmdEYW0rVGhyaXBzRGFtK0Zlcm4rKDF8RmFtaWx5KSsoMXxnaF9iZW5jaC9naF9jb2wpLCBkYXRhPWRhdDIpCgpmaXRmdWxsMzwtbG1lcihHTV9Ub3RhbExlYWZfQXJlYX50cmVhdG1lbnQqZ2x1Y19Db25jKmZsYXZfQ29uYytCbGFja1BhdGhEYW0rV2hpdGVGdW5nRGFtK1Rocmlwc0RhbStGZXJuKygxfEZhbWlseSkrKDF8Z2hfYmVuY2gpLCBkYXRhPWRhdDIpCgpmaXRmdWxsNDwtbG1lcihHTV9Ub3RhbExlYWZfQXJlYX50cmVhdG1lbnQqZ2x1Y19Db25jKmZsYXZfQ29uYytCbGFja1BhdGhEYW0rV2hpdGVGdW5nRGFtK1Rocmlwc0RhbStGZXJuKygxfEZhbWlseSksIGRhdGE9ZGF0MikKCmZpdGZ1bGw1PC1sbWVyKEdNX1RvdGFsTGVhZl9BcmVhfnRyZWF0bWVudCpnbHVjX0NvbmMqZmxhdl9Db25jK0JsYWNrUGF0aERhbStXaGl0ZUZ1bmdEYW0rVGhyaXBzRGFtK0Zlcm4rKDF8Z2hfYmVuY2gpLCBkYXRhPWRhdDIpCgpmaXRmdWxsNjwtbG1lcihHTV9Ub3RhbExlYWZfQXJlYX50cmVhdG1lbnQqZ2x1Y19Db25jKmZsYXZfQ29uYytCbGFja1BhdGhEYW0rV2hpdGVGdW5nRGFtK1Rocmlwc0RhbStGZXJuKygxfGdoX2JlbmNoL2doX2NvbCksIGRhdGE9ZGF0MikKCmFub3ZhKGZpdGZ1bGwwLGZpdGZ1bGwyLGZpdGZ1bGwzLGZpdGZ1bGw0LGZpdGZ1bGw1LGZpdGZ1bGw2KSAjQmVzdCBtb2RlbCBpcyBmaXRmdWxsNiBhbmQgZml0ZnVsbDIuIEkgd2lsbCBjb21wYXJlIHRoZXNlIHR3byBkaXJlY3RseQphbm92YShmaXRmdWxsNixmaXRmdWxsMikgI0ZhbWlseSBpcyBub3QgYSBzaWduaWZpY2FudCBwcmVkaWN0b3IgYW5kIHdpbGwgYmUgZXhjbHVkZWQsIGJ1dCBncmVlbmhvdXNlIGxvY2F0aW9uIGlzIGFuZCB3aWxsIGJlIGluY2x1ZGVkLiAKCiNNb2RlbGxpbmcgZml4ZWQgZWZmZWN0cy4gLS0tLS0tLS0tLS0KCiNGdWxsIE1vZGVsCmZpdGZ1bGwzPC1sbWVyKEdNX1RvdGFsTGVhZl9BcmVhfnRyZWF0bWVudCpnbHVjX0NvbmMqZmxhdl9Db25jK0JsYWNrUGF0aERhbStXaGl0ZUZ1bmdEYW0rVGhyaXBzRGFtK0Zlcm4rKDF8Z2hfYmVuY2gvZ2hfY29sKSwgZGF0YT1kYXQyKQoKI1JlbW92aW5nIHRocmVlIHdheSBpbnRlcmFjdGlvbgpmaXQuMTwtdXBkYXRlKGZpdGZ1bGwzLCB+Li10cmVhdG1lbnQ6Z2x1Y19Db25jOmZsYXZfQ29uYykKYW5vdmEoZml0ZnVsbDMsZml0LjEpICNHb29kIHRvIHJlbW92ZQoKI1JlbW92aW5nIHR3byB3YXkgaW50ZXJhY3Rpb24gZ2x1YzpmbGF2CmZpdC4yPC11cGRhdGUoZml0LjEsfi4tZ2x1Y19Db25jOmZsYXZfQ29uYykKYW5vdmEoZml0LjIsZml0LjEpICNHb29kIHRvIHJlbW92ZS4gCgojUmVtb3ZpbmcgdHJlYXRtZW50OmZsYXZvbm9pZCBpbnRlcmFjdGlvbnMKZml0LjM8LXVwZGF0ZShmaXQuMix+Li10cmVhdG1lbnQ6Zmxhdl9Db25jKQphbm92YShmaXQuMixmaXQuMykgI0dvb2QgdG8gcmVtb3ZlLiAKCgojRmxhdm9ub2lkIENvbmNlbnRyYXRpb24gaGFzIG1pc3Npbmcgc2FtcGxlcy4gVGhlcmVmb3JlLCBJIGZpdCB0d28gbW9kZWxzLCBvbmUgaW5jbHVkaW5nIGZsYXZfQ29uYyBhbmQgb25lIHRoYXQgZG9lcyBub3Q7IGhvd2V2ZXIsIGJvdGggdXNlIHRoZSBzYW1lIGxpbWl0ZWQgZGF0YXNldC4KI05vIGZsYXZfQ29uYwpmaXQuNDwtbG1lcihHTV9Ub3RhbExlYWZfQXJlYSB+IHRyZWF0bWVudCArIGdsdWNfQ29uYyArIEJsYWNrUGF0aERhbSArIFdoaXRlRnVuZ0RhbSArICAKICAgIFRocmlwc0RhbSArIEZlcm4gKyAgIHRyZWF0bWVudDpnbHVjX0NvbmMgKyAoMSB8IGdoX2JlbmNoL2doX2NvbCkgICxkYXRhPWRhdDJbIWlzLm5hKGRhdDIkZmxhdl9Db25jKSxdKQojWWVzIGZsYXZfQ29uYwpmaXQuMzwtbG1lcihHTV9Ub3RhbExlYWZfQXJlYSB+IHRyZWF0bWVudCArIGdsdWNfQ29uYyArIEJsYWNrUGF0aERhbSArIFdoaXRlRnVuZ0RhbSArICAKICAgIFRocmlwc0RhbSArIEZlcm4gKyAgIHRyZWF0bWVudDpnbHVjX0NvbmMrZmxhdl9Db25jICsgKDEgfCBnaF9iZW5jaC9naF9jb2wpICAsZGF0YT1kYXQyWyFpcy5uYShkYXQyJGZsYXZfQ29uYyksXSkKCmFub3ZhKGZpdC4zLGZpdC40KSAjRmxhdl9Db25jIGlzIGEgc2lnbmlmaWNhbnQgcHJlZGljdG9yLiAKCiNOb3cgdGhhdCBJIGtub3cgZmxhdl9jb25jIGlzIHNpZ25pZmljYW50LCBJIHdpbGwgY29uZHVjdCB0aGUgcmVzdCBvZiB0aGUgbW9kZWwgc2ltcGxpZmljYXRpb24gdXNpbmcgdGhlIHdob2xlIGRhdGEgc2V0IChpLmUuIGZsYXZfQ29uYyBleGNsdWRlZCAtLWZpdDQpIAoKCgpmaXQubmY8LWxtZXIoR01fVG90YWxMZWFmX0FyZWEgfiB0cmVhdG1lbnQgKyBnbHVjX0NvbmMgKyBCbGFja1BhdGhEYW0gKyBXaGl0ZUZ1bmdEYW0gKyAgCiAgICBUaHJpcHNEYW0gKyBGZXJuICsgICB0cmVhdG1lbnQ6Z2x1Y19Db25jKyAoMSB8IGdoX2JlbmNoL2doX2NvbCkgICxkYXRhPWRhdDIpCgpmaXQuMC5uZjwtdXBkYXRlKGZpdC5uZix+Li10cmVhdG1lbnQ6Z2x1Y19Db25jKQphbm92YShmaXQuMC5uZixmaXQubmYpICAjVGhlIGludGVyYWN0aW9uIGlzIHJpZ2h0IG9uIHRoZSB2ZXJnZSBvZiBzaWduaWZpY2FuY2UsIEkgd2lsbCBrZWVwIGl0IGluY2x1ZGVkLiAKCiNDcmVhdGluZyBhIHN1YnNldHRlZCBkYXRhZnJhbWUgZm9yIHRoZSBibGFjayBwYXRob2dlbiBkYW1hZ2UuIApmaXQubmYuYnA8LWxtZXIoR01fVG90YWxMZWFmX0FyZWEgfiB0cmVhdG1lbnQgKyBnbHVjX0NvbmMgKyBCbGFja1BhdGhEYW0gKyBXaGl0ZUZ1bmdEYW0gKyAgCiAgICBUaHJpcHNEYW0gKyBGZXJuICsgICB0cmVhdG1lbnQ6Z2x1Y19Db25jKyAoMSB8IGdoX2JlbmNoL2doX2NvbCkgICxkYXRhPWRhdDJbIWlzLm5hKGRhdDIkQmxhY2tQYXRoRGFtKSxdKQoKZml0LjEubmY8LXVwZGF0ZShmaXQubmYuYnAsfi4tQmxhY2tQYXRoRGFtKQphbm92YShmaXQubmYuYnAsZml0LjEubmYpICNCbGFjayBwYXRob2dlbiBkYW1hZ2UgaXMgYSB2ZXJ5IHNpZ25pZmljYW50IHByZWRpY3Rvci4gRGlkIG5vdCByZW1vdmUuCgpmaXQuMi5uZjwtdXBkYXRlKGZpdC5uZix+Li1XaGl0ZUZ1bmdEYW0pCmFub3ZhKGZpdC5uZixmaXQuMi5uZikgICNXaGl0ZSBGdW5nYWwgRGFtYWdlIHdhcyBub3Qgc2lnbmlmaWNhbnQsIGhvd2V2ZXIsIGJvdGggdGhlIEFJQyBhbmQgQklDIHdhcyBsb3dlciB3aXRoIGl0IGluY2x1ZGVkLCBzdWdnZXN0aW5nIGl0IG1heSBiZSBhbiBpbXBvcnRhbnQgdmFyaWFibGUuIAoKCiNSZWZpdHRpbmcgYSBtb2RlbCBmb3IgdGhyaXBzIGRhbSAKZml0Lm5mPC1sbWVyKEdNX1RvdGFsTGVhZl9BcmVhIH4gdHJlYXRtZW50ICsgZ2x1Y19Db25jICsgQmxhY2tQYXRoRGFtICsgIAogICAgVGhyaXBzRGFtICsgRmVybiArICAgdHJlYXRtZW50OmdsdWNfQ29uYysgKDEgfCBnaF9iZW5jaC9naF9jb2wpICAsZGF0YT1kYXQyWyFpcy5uYShkYXQyJFRocmlwc0RhbSksXSkKCmZpdC4zLm5mPC11cGRhdGUoZml0Lm5mLH4uLVRocmlwc0RhbSkKYW5vdmEoZml0Lm5mLGZpdC4zLm5mKSAgI1RocmlwcyBEYW1hZ2Ugd2FzIGFsc28gbm90IGEgc2lnbmlmaWNhbnQgcHJlZGljdG9yLCBob3dldmVyLCBib3RoIHRoZSBBSUMgYW5kIEJJQyB3YXMgbG93ZXIgd2l0aCBpdCBpbmNsdWRlZCwgc3VnZ2VzdGluZyBpdCBtYXkgYmUgYW4gaW1wb3J0YW50IHByZWRpY3Rvci4gCgoKZml0Lm5mPC1sbWVyKEdNX1RvdGFsTGVhZl9BcmVhIH4gdHJlYXRtZW50ICsgZ2x1Y19Db25jICsgQmxhY2tQYXRoRGFtICsgIAogICAgVGhyaXBzRGFtICsgIEZlcm4rICB0cmVhdG1lbnQ6Z2x1Y19Db25jKyAoMSB8IGdoX2JlbmNoL2doX2NvbCkgICxkYXRhPWRhdDIpCgpmaXQuNC5uZjwtdXBkYXRlKGZpdC5uZix+Li1GZXJuKQphbm92YShmaXQubmYsZml0LjQubmYpICAjRmVybiBhYnVuZGFuY2UgaXMgc2lnbmlmaWNuYXQgcHJlZGljdG9yIHBlcmZvcm1hbmNlLgoKCmxpYnJhcnkobG1lclRlc3QpCiNUaGUgYmVzdCBtb2RlbCBpcyB0aGVyZWZvcmU6IAoKI1dpdGggbGltaXRlZCBkYXRhc2V0IGNvbnRhaW5pbmcgZmxhdm9ub2lkIGRhdGEKc3VtbWFyeShsbWVyKEdNX1RvdGFsTGVhZl9BcmVhIH4gdHJlYXRtZW50KmdsdWNfQ29uYytGZXJuK0JsYWNrUGF0aERhbSArZmxhdl9Db25jICsgKDEgfCBnaF9iZW5jaC9naF9jb2wpICxkYXRhPWRhdDIpKQoKI3dpdGggd2hvbGUgZGF0YSBzZXQgbGFja2luZyBmbGF2b25vaWQgZGF0YQpzdW1tYXJ5KGxtZXIoR01fVG90YWxMZWFmX0FyZWEgfiB0cmVhdG1lbnQqZ2x1Y19Db25jK0Zlcm4rQmxhY2tQYXRoRGFtICArICgxIHwgZ2hfYmVuY2gvZ2hfY29sKSAsZGF0YT1kYXQyKSkKCiNUaGUgbmVnYXRpdmUgc2xvcGUgYXNzb2NpYXRlZCB3aXRoIHRoZSBhbG9uZSB0cmVhbXRtZW50IGlzIG5vIGxvbmdlciBzaWduaWZpY2FudCwgc3VnZ2VzdGluZyB0aGF0IHRoZXJlIGlzIG9ubHkgYSBwb3N0aXZlIHNsb3BlIG9mIGdsdWNvc2lub2xhdGVzIGluIHRoZSBtYXBsZSB0cmVhdG1lbnQuIEhvd2V2ZXIsIHRoZSBpc3N1ZSB3aXRoIHRoaXMgYW5hbHlzaXMgaXMgdGhhdCBpcyBkb2VzIG5vdCBhY2NvdW50IGZvciB0aGUgY29tcGV0aXRpdmUgc3RyZW5ndGggb2YgdGhlIG1hcGxlIGNvbXBldGl0b3IsIHdoaWNoIG1heSBiZSBjb3JyZWxhdGVkIHdpdGggZ2x1Y29zaW5vbGF0ZSBjb25jZW50cmF0aW9uLiAKCiNNb2RlbHMgd2l0aCBUaHJpcHMgZGFtYWdlIGFuZCB3aGl0ZSBwYXRob2dlbiBkYW1hZ2UgZXhoaWJpdGVkIGxvd2VyIEFJQyBhbmQgQklDIHZhbHVlcyB0aGFuIHRob3NlIHdpdGhvdXQsIGhvd2V2ZXIsIHRoZSBsaWtlbHlob29kIHJhdGlvIHRlc3Qgd2FzIG5vdCBzaWduaWZpY2FudC4gQ2FuIEkgdXNlIHBvaXNzb24gZGF0YSBhcyBhIHByZWRpY3RvciBpbiB0aGlzIG1vZGVsPyBTaG91bGQgaSBsb2cgdHJhbnNmb3JtIGl0PyBJIGFtIG5vdCBzdXJlLiAKCgoKYGBgCgoKI01vZGVsIERpYWdub3N0aWNzLiAKYGBge3J9CiNHbHVjQ29uY0ludGVyYWN0aW9uCmZpdC5XaG9sZTwtbG1lcihHTV9Ub3RhbExlYWZfQXJlYSB+IHRyZWF0bWVudCpnbHVjX0NvbmMgKyBCbGFja1BhdGhEYW0rRmVybitmbGF2X0NvbmMgKyAoMSB8IGdoX2JlbmNoL2doX2NvbCkgLGRhdGE9ZGF0MikKCmNvbmZpbnQoZml0Lldob2xlKQoKY29lZihmaXQuV2hvbGUpCiNubyBoZXRlcm9zY2VkYXN0aWNpdHkKcGxvdChmaXQuV2hvbGUpCiNmYWlybHkgbm9ybWFsLiAKcXFub3JtKHJlc2lkKGZpdC5XaG9sZSkpCgojVGhlIG1vZGVsIGFwcGVhcnMgdG8gYmUgYSBnb29kIGZpdC4KYGBgCgoKI1Zpc3VhbGl6YXRpb24gLS0gVGhlIGNvbmRpdGlvbmFsIGJlbmVmaXQgb2YgZ2x1Y29zaW5vbGF0ZXMgKGFsbGVsb3BhdGh5KQpgYGB7cn0KCmFsb25lU2xvcGU8LWZ1bmN0aW9uKHgpewogIHk9LTM5NjYuNjAqeCsgMTM3NTEuOTYKICByZXR1cm4oeSkKfQptYXBsZVNsb3BlPC1mdW5jdGlvbih4KXsKICB5PSgtNDI1NC4yKzg0MTcuOTUpKngrMTM3NTEuOTYgLTkyNDMuNzEKICByZXR1cm4oeSkKfQoKbXVzdGFyZFNsb3BlPC1mdW5jdGlvbih4KXsKICB5PSsxMzc1MS45Ni04Mzc2LjY3I05vbiBzaWduaWZpY2FudCBzbG9wZQogIHJldHVybih5KQp9CgptaW5NPC1taW4oZGF0MiRnbHVjX0NvbmNbZGF0MiR0cmVhdG1lbnQ9PSJtIl0sbmEucm0gPSBUKQptYXhNPC1tYXgoZGF0MiRnbHVjX0NvbmNbZGF0MiR0cmVhdG1lbnQ9PSJtIl0sbmEucm0gPSBUKQoKbWluQTwtbWluKGRhdDIkZ2x1Y19Db25jW2RhdDIkdHJlYXRtZW50PT0iYSJdLG5hLnJtID0gVCkKbWF4QTwtbWF4KGRhdDIkZ2x1Y19Db25jW2RhdDIkdHJlYXRtZW50PT0iYSJdLG5hLnJtID0gVCkKCm1pbkc8LW1pbihkYXQyJGdsdWNfQ29uY1tkYXQyJHRyZWF0bWVudD09ImdtIl0sbmEucm0gPSBUKQptYXhHPC1tYXgoZGF0MiRnbHVjX0NvbmNbZGF0MiR0cmVhdG1lbnQ9PSJnbSJdLG5hLnJtID0gVCkKCiN0aWZmKCJTZWxlY3Rpb25fRmlndXJlcy9HbHVjX0JlbmVmaXQudGlmZiIsIHVuaXRzPSJpbiIsIHdpZHRoPTEwLCBoZWlnaHQ9NiwgcmVzPTMwMCkKbGlicmFyeShnZ3Bsb3QyKQpnZ3Bsb3QoZGF0MikrCiAgZ2VvbV9wb2ludChhZXMoeT1HTV9Ub3RhbExlYWZfQXJlYSx4PWdsdWNfQ29uYyxjb2xvdXI9dHJlYXRtZW50KSxzaXplPTIpKwogIGdlb21fc2VnbWVudCh4PW1pbkEseGVuZD1tYXhBLHk9YWxvbmVTbG9wZShtaW5BKSx5ZW5kPWFsb25lU2xvcGUobWF4QSksY29sb3VyPSIjMDA5RTczIixzaXplPTEuNSkrCiAgICBnZW9tX3NlZ21lbnQoeD1taW5NLHhlbmQ9bWF4TSx5PW1hcGxlU2xvcGUobWluTSkseWVuZD1tYXBsZVNsb3BlKG1heE0pLGNvbG91cj0iI0U2OUYwMCIsc2l6ZT0xLjUpKwogIGdlb21fc2VnbWVudCh4PW1pbkcseGVuZD1tYXhHLHk9bXVzdGFyZFNsb3BlKG1pbkcpLHllbmQ9bXVzdGFyZFNsb3BlKG1heEcpLGNvbG91cj0iIzU2QjRFOSIsc2l6ZT0xLjUpK3RoZW1lX3NpbXBsZSgpKwogIHlsYWIoYnF1b3RlKGJvbGQoIlBlcmZvcm1hbmNlXG4oVG90YWwgTGVhZiBBcmVhICJ+KG1tXjIpfiIpIikpKSt4bGFiKGJxdW90ZShib2xkKCJbVG90YWwgR2x1Y29zaW5vbGF0ZV0gIiAobWcvbWwpKSkpKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPWMoIiMwMDlFNzMiLCIjNTZCNEU5IiwiI0U2OUYwMCIpLGxhYmVscz1jKCJBbG9uZSIsIkdhcmxpYyBNdXN0YXJkIiwiTWFwbGUiKSkKI2Rldi5vZmYoKQoKbWluQQoKCmBgYAoKI1Zpc3VhbGl6aW5nIHRoZSBlZmZlY3Qgb2YgZmxhdm9ub2lkIG9uIGZpdG5lc3MuCmBgYHtyfQpzdW1tYXJ5KGxtZXIoR01fVG90YWxMZWFmX0FyZWF+dHJlYXRtZW50K2ZsYXZfQ29uYytCbGFja1BhdGhEYW0rRmVybisoMXxGYW1pbHkpKygxfGdoX2JlbmNoL2doX2NvbCksIGRhdGE9ZGF0MikpCgphbG9uZVNsb3BlPC1mdW5jdGlvbih4KXsKICB5PTIwMjQuNjIgKngrICA4MDM1LjMwCiAgcmV0dXJuKHkpCn0KbWFwbGVTbG9wZTwtZnVuY3Rpb24oeCl7CiAgeT0oMjAyNC42MiApKngrIDgwMzUuMzAgLTEwNjcuMDIKICByZXR1cm4oeSkKfQoKbXVzdGFyZFNsb3BlPC1mdW5jdGlvbih4KXsKICB5PTIwMjQuNjIgKngrIDgwMzUuMzAtMzc0Ni45MSNOb24gc2lnbmlmaWNhbnQgc2xvcGUKICByZXR1cm4oeSkKfQoKbWluTTwtbWluKGRhdDIkZmxhdl9Db25jW2RhdDIkdHJlYXRtZW50PT0ibSJdLG5hLnJtID0gVCkKbWF4TTwtbWF4KGRhdDIkZmxhdl9Db25jW2RhdDIkdHJlYXRtZW50PT0ibSJdLG5hLnJtID0gVCkKCm1pbkE8LW1pbihkYXQyJGZsYXZfQ29uY1tkYXQyJHRyZWF0bWVudD09ImEiXSxuYS5ybSA9IFQpCm1heEE8LW1heChkYXQyJGZsYXZfQ29uY1tkYXQyJHRyZWF0bWVudD09ImEiXSxuYS5ybSA9IFQpCgptaW5HPC1taW4oZGF0MiRmbGF2X0NvbmNbZGF0MiR0cmVhdG1lbnQ9PSJnbSJdLG5hLnJtID0gVCkKbWF4RzwtbWF4KGRhdDIkZmxhdl9Db25jW2RhdDIkdHJlYXRtZW50PT0iZ20iXSxuYS5ybSA9IFQpCgoKI3RpZmYoIlNlbGVjdGlvbl9GaWd1cmVzL0ZsYXZfQmVuZWZpdC50aWZmIiwgdW5pdHM9ImluIiwgd2lkdGg9MTAsIGhlaWdodD02LCByZXM9MzAwKQpnZ3Bsb3QoZGF0MikrCiAgZ2VvbV9wb2ludChhZXMoeT1HTV9Ub3RhbExlYWZfQXJlYSx4PWZsYXZfQ29uYyxjb2xvdXI9dHJlYXRtZW50KSxzaXplPTIpKwogIGdlb21fc2VnbWVudCh4PW1pbkEseGVuZD1tYXhBLHk9YWxvbmVTbG9wZShtaW5BKSx5ZW5kPWFsb25lU2xvcGUobWF4QSksY29sb3VyPSIjMDA5RTczIixzaXplPTEuNSkrCiAgICBnZW9tX3NlZ21lbnQoeD1taW5NLHhlbmQ9bWF4TSx5PW1hcGxlU2xvcGUobWluTSkseWVuZD1tYXBsZVNsb3BlKG1heE0pLGNvbG91cj0iI0U2OUYwMCIsc2l6ZT0xLjUpK3RoZW1lX3NpbXBsZSgpKwogIGdlb21fc2VnbWVudCh4PW1pbkcseGVuZD1tYXhHLHk9bXVzdGFyZFNsb3BlKG1pbkcpLHllbmQ9bXVzdGFyZFNsb3BlKG1heEcpLGNvbG91cj0iIzU2QjRFOSIsc2l6ZT0xLjUpK3RoZW1lX3NpbXBsZSgpKwogIHlsYWIoYnF1b3RlKGJvbGQoIlBlcmZvcm1hbmNlXG4oVG90YWwgTGVhZiBBcmVhICJ+KG1tXjIpfiIpIikpKSt4bGFiKGJxdW90ZShib2xkKCJbVG90YWwgRmxhdm9ub2lkXSAiIChtZy9tbCkpKSkrCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9YygiIzAwOUU3MyIsIiM1NkI0RTkiLCIjRTY5RjAwIiksbGFiZWxzPWMoIkFsb25lIiwiR2FybGljIE11c3RhcmQiLCJNYXBsZSIpKQojZGV2Lm9mZigpCmBgYAoKI1Zpc3VhbGl6YXRpb24tLSBUaGUgRGV0cmltZW50IG9mIHBhdGhvZ2VucyBhbmQgZmVybnMKYGBge3J9CnN1bW1hcnkobG1lcihHTV9Ub3RhbExlYWZfQXJlYSB+IEZlcm4rCigxIHwgRmFtaWx5KSArICgxIHwgZ2hfYmVuY2gvZ2hfY29sKSAsZGF0YT1kYXQyKSkKCmE8LWdncGxvdChkYXQyKSsKICBnZW9tX3BvaW50KGFlcyh5PUdNX1RvdGFsTGVhZl9BcmVhLHg9QmxhY2tQYXRoRGFtKSkrdGhlbWVfc2ltcGxlX211bHRpQ29sKCkrCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0PTgyODEuNzYsc2xvcGUgPSAtMTA1LjI4LHNpemU9MS41KSsKICB4bGFiKCJCbGFjayBQYXRob2dlbiBEYW1hZ2UiKQoKYjwtZ2dwbG90KGRhdDJbZGF0MiRXaGl0ZUZ1bmdEYW08MzAsXSkrCiAgZ2VvbV9wb2ludChhZXMoeT1HTV9Ub3RhbExlYWZfQXJlYSx4PVdoaXRlRnVuZ0RhbSksY29sb3VyPSIjOTk5OTk5IikrdGhlbWVfc2ltcGxlX211bHRpQ29sKCkrCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gIiM5OTk5OTkiLCBzaXplID0gMTYsIGZhY2UgPSAiYm9sZCIsbWFyZ2luPW1hcmdpbigzLDAsMywwKSksCiAgICAgICkreGxhYigiUG93ZGVyeSBNaWxkZXcgRGFtYWdlIikKCmM8LWdncGxvdChkYXQyKSsKICBnZW9tX3BvaW50KGFlcyh5PUdNX1RvdGFsTGVhZl9BcmVhLHg9VGhyaXBzRGFtKSxjb2xvdXI9IiNFNjlGMDAiKSt0aGVtZV9zaW1wbGVfbXVsdGlDb2woKSt4bGFiKCJUaHJpcHMgRGFtYWdlIikrCiAgICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiI0U2OUYwMCIsIHNpemUgPSAxNiwgZmFjZSA9ICJib2xkIixtYXJnaW49bWFyZ2luKDMsMCwzLDApKSkKCmQ8LWdncGxvdChkYXQyKSsKICBnZW9tX3BvaW50KGFlcyh5PUdNX1RvdGFsTGVhZl9BcmVhLHg9RmVybiksY29sb3VyPSIjMDA5RTczIikrdGhlbWVfc2ltcGxlX211bHRpQ29sKCkreGxhYigiRmVybiBBYnVuZGFuY2UiKSsKICAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0PTgwMDMuNDQsc2xvcGUgPSAtMTc5LjQ3LHNpemU9MS41LGNvbG9yPSIjMDA5RTczIikrCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gIiMwMDlFNzMiLCBzaXplID0gMTYsIGZhY2UgPSAiYm9sZCIsbWFyZ2luPW1hcmdpbigzLDAsMywwKSkpCiAgIAoKCnBsb3Q8LXBsb3RfZ3JpZChhLCBiLG5jb2w9MixyZWxfd2lkdGhzID0gYygxLDEpKQoKcGxvdDI8LXBsb3RfZ3JpZChkLCBjLG5jb2w9MixyZWxfd2lkdGhzID0gYygxLDEpKQoKcGxvdDM8LXBsb3RfZ3JpZChhLGIsYyxkLG5jb2w9MixyZWxfd2lkdGhzID0gYygxLDEpKQoKcGxvdDQ8LXBsb3RfZ3JpZChhLGIsYyxuY29sPTEscmVsX3dpZHRocyA9IGMoMSwxLDEpKQpwbG90NTwtcGxvdF9ncmlkKGEsYixjLG5jb2w9MyxyZWxfd2lkdGhzID0gYygxLDEsMSkpCgoKeS5ncm9iPC10ZXh0R3JvYihicXVvdGUoYm9sZCgiU2hvb3QgQXJlYSAiKG1tXjIpKSksZ3A9Z3Bhcihmb250ZmFjZT0iYm9sZCIsZm9udHNpemU9MjApLHJvdD05MCkKCgojdGlmZigiU2VsZWN0aW9uX0ZpZ3VyZXMvUGF0aG9nZW5FZmZlY3QudGlmZiIsIHVuaXRzPSJpbiIsIHdpZHRoPTE0LCBoZWlnaHQ9NiwgcmVzPTMwMCkKZ3JpZC5hcnJhbmdlKHBsb3QsbGVmdD15Lmdyb2IpCiNkZXYub2ZmKCkKCiN0aWZmKCJTZWxlY3Rpb25fRmlndXJlcy9QYXRob2dlbkVmZmVjdDIudGlmZiIsIHVuaXRzPSJpbiIsIHdpZHRoPTE0LCBoZWlnaHQ9NiwgcmVzPTMwMCkKZ3JpZC5hcnJhbmdlKHBsb3QyLGxlZnQ9eS5ncm9iKQojZGV2Lm9mZigpCgojdGlmZigiU2VsZWN0aW9uX0ZpZ3VyZXMvUGF0aG9nZW5FZmZlY3QzLnRpZmYiLCB1bml0cz0iaW4iLCB3aWR0aD0xNCwgaGVpZ2h0PTEwLCByZXM9MzAwKQpncmlkLmFycmFuZ2UocGxvdDMsbGVmdD15Lmdyb2IpCiNkZXYub2ZmCgpncmlkLmFycmFuZ2UocGxvdDQsbGVmdD15Lmdyb2IpCgoKI3RpZmYoIlNlbGVjdGlvbl9GaWd1cmVzL1BhdGhvZ2VuRWZmZWN0NS50aWZmIiwgdW5pdHM9ImluIiwgd2lkdGg9MTYsIGhlaWdodD01LCByZXM9MzAwKQpncmlkLmFycmFuZ2UocGxvdDUsbGVmdD15Lmdyb2IpCiNkZXYub2ZmCgojdGlmZigiU2VsZWN0aW9uX0ZpZ3VyZXMvRmVybkVmZmVjdC50aWZmIiwgdW5pdHM9ImluIiwgd2lkdGg9OCwgaGVpZ2h0PTYsIHJlcz0zMDApCmdyaWQuYXJyYW5nZShkLGxlZnQ9eS5ncm9iKQojZGV2Lm9mZgoKYGBgCgoKCiMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojUGFydCAyCgoKCgojSW5mbHVlbmNlIG9mIGdsdWMgYW5kIGZsYXYgb24gZGVmZW5jZS4gCmBgYHtyfQoKaGlzdChkYXQkRmVybikKaGlzdChkYXQkVGhyaXBzRGFtKQpoaXN0KGRhdCRXaGl0ZUZ1bmdEYW0pCmhpc3QoZGF0JEJsYWNrUGF0aERhbSkKCmRhdCRCbGFja1BhdGhEYW0KCiNUaGlzIGRhdGEgaXMgdmVyeSB6ZXJvIGluZmxhdGVkIGFuZCBhIHBvaXNzb24gbW9kZWwgd2lsbCBiZSB0b28gb3ZlcmRpc3BlcnNlZC4gSSBhbSBhZnJhaWQgdGhhdCBhIG5lZ2F0aXZlIGJpbm9taWFsIHdpbGwgYmUgYXMgd2VsbC4gCmBgYAoKCiNTaWduaWZpY2FudCB0ZXN0aW5nIAoKCgojV2hpdGVQYXRoRGFtIC0tIGxvZ2lzdGljIHJlZ3Jlc3Npb24gCmBgYHtyfQojQmVjYXVzZSBvZiBob3cgemVybyBpbmZsYXRlZCB3aGl0ZSBwYXRob2dlbiBkYW1hZ2UgaXMsIGkgd2lsbCB1c2UgYSBsb2dpc3RpYyByZWdyZXNzaW9uIHRvIG1vZGVsIGl0LgpkYXQyJFdoaXRlRnVuZ0xvZ2lzPC1OQQpkYXQyJFdoaXRlRnVuZ0xvZ2lzW2RhdDIkV2hpdGVGdW5nRGFtPT0wXTwtMApkYXQyJFdoaXRlRnVuZ0xvZ2lzW2RhdDIkV2hpdGVGdW5nRGFtPjBdPC0xCgoKI1RoaXMgaXMgdGhlIGJpZ2dlc3QgbW9kZWwgdGhhdCBjb3VsZCBjb252ZXJnZS4gLi4uIGludGVyYWN0aW9uIHdpdGggZmxhdm9ub2lkIGNvdWxkIG5vdC4KZml0X2Z1bGxfZzwtZ2xtZXIoV2hpdGVGdW5nTG9naXN+dHJlYXRtZW50KmdsdWNfQ29uYytmbGF2X0NvbmMrKDF8RmFtaWx5KSxmYW1pbHk9Ymlub21pYWwsZGF0YT1kYXQyWyFpcy5uYShkYXQyJGZsYXZfQ29uYyksXSkKCmZpdC4xPC11cGRhdGUoZml0X2Z1bGxfZyx+Li1mbGF2X0NvbmMpCmFub3ZhKGZpdF9mdWxsX2csZml0LjEpICNGbGF2b25vaWQgQ29uY2VudHJhdGlvbiBpcyBub3Qgc2lnbmlmaWNhbnQuIAoKCiNUZXN0aW5nIGdsdWNvc2lub2xhdGUgdHJlYXRtZW50IGludGVyYWN0aW9uLiAKZml0LjI8LWdsbWVyKFdoaXRlRnVuZ0xvZ2lzfnRyZWF0bWVudCpnbHVjX0NvbmMrKDF8RmFtaWx5KSxmYW1pbHk9Ymlub21pYWwsZGF0YT1kYXQyKQpmaXQuMzwtZ2xtZXIoV2hpdGVGdW5nTG9naXN+dHJlYXRtZW50K2dsdWNfQ29uYysoMXxGYW1pbHkpLGZhbWlseT1iaW5vbWlhbCxkYXRhPWRhdDIpCmFub3ZhKGZpdC4yLGZpdC4zKSAjR2x1Y29zaW5vbGF0ZTpUcmVhdG1lbnQgaW50ZXJhY3Rpb24gaXMgbm90IHNpZ25pZmljYW50LgoKI1Rlc3RpbmcgZ2x1Y29zaW5vbGF0ZSBpbnZvbHZtZW50IGF0IGFsbC4KZml0LjQ8LWdsbWVyKFdoaXRlRnVuZ0xvZ2lzfnRyZWF0bWVudCsoMXxGYW1pbHkpLGZhbWlseT1iaW5vbWlhbCxkYXRhPWRhdDJbIWlzLm5hKGRhdDIkZ2x1Y19Db25jKSxdKQpmaXQuMzwtZ2xtZXIoV2hpdGVGdW5nTG9naXN+dHJlYXRtZW50K2dsdWNfQ29uYysoMXxGYW1pbHkpLGZhbWlseT1iaW5vbWlhbCxkYXRhPWRhdDJbIWlzLm5hKGRhdDIkZ2x1Y19Db25jKSxdKQphbm92YShmaXQuNCxmaXQuMykgI0dsdWNvc2lub2xhdGUgQ29uY2VudHJhdGlvbiBpcyBub3QgYSBzaWduaWZpY2FudCBwcmVkaWN0b3IKCiNUZXN0aW5nIGVmZmVjdCBvZiB0cmVhdG1lbnQKZml0LjQ8LWdsbWVyKFdoaXRlRnVuZ0xvZ2lzfnRyZWF0bWVudCsoMXxGYW1pbHkpLGZhbWlseT1iaW5vbWlhbCxkYXRhPWRhdDIpCmZpdC41PC1nbG1lcihXaGl0ZUZ1bmdMb2dpc34xKygxfEZhbWlseSksZmFtaWx5PWJpbm9taWFsLGRhdGE9ZGF0MikKYW5vdmEoZml0LjQsZml0LjUpCiN0cmVhdG1lbnQgaXMgc2lnbmlmaWNhbnQuLi4uLi4KCnN1bW1hcnkoZml0LjQpICNHYXJsaWMgbXVzdGFyZCBpbiB0aGUgbWFwbGUgdHJlYXRtZW50IGhhdmUgbGVzcyBvY2N1cmVuY2Ugb2YgZnVuZ2FsIGNvbG9uaXphdGlvbi4gCgpwbG90KGZpdC40KQpgYGAKCiNWaXN1YWxpemluZyAtLSBlZmZlY3Qgb2YgdHJlYXRtZW50IG9uIHByb3BvcnRpb24gb2YgZnVuZ2FsIGFidW5kYW5jZS4gCmBgYHtyfQojU3VtbWFyaXppbmcgZm9yIERpc3BsYXk6IGdlbmVyYXRpbmcgZnJlcXVlbmN5IG9mIHdoaXRlIGZ1bmFsIGluZmVjdGlvbiBieSB0cmVhdG1lbnQKcGxvdDwtZGF0MiAlPiUgZHJvcF9uYShXaGl0ZUZ1bmdMb2dpcykgJT4lIGdyb3VwX2J5KHRyZWF0bWVudCkgJT4lIHN1bW1hcml6ZShQZXJjV2hpdEZ1bmc9c3VtKFdoaXRlRnVuZ0xvZ2lzKS9sZW5ndGgoV2hpdGVGdW5nTG9naXMpKjEwMCkKCgojdGlmZigiRGVmZW5jZV9GaWd1cmVzL1RyZWF0TWVhbldoaXRlRnVuZy50aWZmIiwgdW5pdHM9ImluIiwgd2lkdGg9OCwgaGVpZ2h0PTUsIHJlcz0zMDApCmdncGxvdChwbG90KSsKICBnZW9tX2NvbChhZXMoeD10cmVhdG1lbnQseT1QZXJjV2hpdEZ1bmcsZmlsbD10cmVhdG1lbnQpKSt0aGVtZV9zaW1wbGUoKSt5bGFiKCJGdW5nYWwgQWJ1bmRhbmNlXG4gKCUgSW5mZWN0ZWQpIikrCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLDMwLDUpKSsKc2NhbGVfeF9kaXNjcmV0ZShuYW1lPSIiLGxhYmVscz1jKCJBbG9uZSIsIkdhcmxpYyBNdXN0YXJkIiwiTWFwbGUiKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIiMwMDlFNzMiLCIjNTZCNEU5IiwiI0U2OUYwMCIpLGxhYmVscz1jKCJBbG9uZSIsIkdhcmxpYyBNdXN0YXJkIiwiTWFwbGUiKSkrCiAgdGhlbWVfc2ltcGxlX211bHRpQ29sKCkrdGhlbWUoYXhpcy50aXRsZS55ID0gIGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAxNiwgZmFjZSA9ICJib2xkIixtYXJnaW49bWFyZ2luKDMsMjAsMywwKSkpCiNkZXYub2ZmKCkKCmBgYAoKCgoKI0JsYWNrUGF0aERhbSAtLSBsb2dpc3RpYyByZWdyZXNzaW9uLS0gKHJlZG8gbmV3IGRhdGEpCmBgYHtyfQojQmVjYXVzZSBvZiBob3cgemVybyBpbmZsYXRlZCB3aGl0ZSBwYXRob2dlbiBkYW1hZ2UgaXMsIGkgd2lsbCB1c2UgYSBsb2dpc3RpYyByZWdyZXNzaW9uIHRvIG1vZGVsIGl0LgpkYXQkQmxhY2tQYXRoTG9naXM8LU5BCmRhdCRCbGFja1BhdGhMb2dpc1tkYXQkQmxhY2tQYXRoRGFtPT0wXTwtMApkYXQkQmxhY2tQYXRoTG9naXNbZGF0JEJsYWNrUGF0aERhbT4wXTwtMQoKI1RoaXMgaXMgdGhlIGJpZ2dlc3QgbW9kZWwgdGhhdCBjb3VsZCBjb252ZXJnZS4gLi4uIGludGVyYWN0aW9uIHdpdGggZmxhdm9ub2lkIGNvdWxkIG5vdC4KZml0X2Z1bGxfZzwtZ2xtZXIoQmxhY2tQYXRoTG9naXN+dHJlYXRtZW50KmdsdWNfQ29uYytmbGF2X0NvbmMrKDF8RmFtaWx5L1RhZyksZmFtaWx5PWJpbm9taWFsLGRhdGE9ZGF0KQoKCmZpdC4xPC11cGRhdGUoZml0X2Z1bGxfZyx+Li1mbGF2X0NvbmMpCmFub3ZhKGZpdF9mdWxsX2csZml0LjEpICNGbGF2b25vaWQgQ29uY2VudHJhdGlvbiBpcyBub3Qgc2lnbmlmaWNhbnQuIAoKCiNUZXN0aW5nIGdsdWNvc2lub2xhdGUgdHJlYXRtZW50IGludGVyYWN0aW9uLiAKZml0LjI8LWdsbWVyKFdoaXRlRnVuZ0xvZ2lzfnRyZWF0bWVudCpnbHVjX0NvbmMrKDF8RmFtaWx5KSxmYW1pbHk9Ymlub21pYWwsZGF0YT1kYXQyKQpmaXQuMzwtZ2xtZXIoV2hpdGVGdW5nTG9naXN+dHJlYXRtZW50K2dsdWNfQ29uYysoMXxGYW1pbHkpLGZhbWlseT1iaW5vbWlhbCxkYXRhPWRhdDIpCmFub3ZhKGZpdC4yLGZpdC4zKSAjR2x1Y29zaW5vbGF0ZTpUcmVhdG1lbnQgaW50ZXJhY3Rpb24gaXMgbm90IHNpZ25pZmljYW50LgoKI1Rlc3RpbmcgZ2x1Y29zaW5vbGF0ZSBpbnZvbHZtZW50IGF0IGFsbC4KZml0LjQ8LWdsbWVyKFdoaXRlRnVuZ0xvZ2lzfnRyZWF0bWVudCsoMXxGYW1pbHkpLGZhbWlseT1iaW5vbWlhbCxkYXRhPWRhdDJbIWlzLm5hKGRhdDIkZ2x1Y19Db25jKSxdKQpmaXQuMzwtZ2xtZXIoV2hpdGVGdW5nTG9naXN+dHJlYXRtZW50K2dsdWNfQ29uYysoMXxGYW1pbHkpLGZhbWlseT1iaW5vbWlhbCxkYXRhPWRhdDJbIWlzLm5hKGRhdDIkZ2x1Y19Db25jKSxdKQphbm92YShmaXQuNCxmaXQuMykgI0dsdWNvc2lub2xhdGUgQ29uY2VudHJhdGlvbiBpcyBub3QgYSBzaWduaWZpY2FudCBwcmVkaWN0b3IKCiNUZXN0aW5nIGVmZmVjdCBvZiB0cmVhdG1lbnQKZml0LjQ8LWdsbWVyKFdoaXRlRnVuZ0xvZ2lzfnRyZWF0bWVudCsoMXxGYW1pbHkpLGZhbWlseT1iaW5vbWlhbCxkYXRhPWRhdDIpCmZpdC41PC1nbG1lcihXaGl0ZUZ1bmdMb2dpc34xKygxfEZhbWlseSksZmFtaWx5PWJpbm9taWFsLGRhdGE9ZGF0MikKYW5vdmEoZml0LjQsZml0LjUpCiN0cmVhdG1lbnQgaXMgc2lnbmlmaWNhbnQuLi4uLi4KCnN1bW1hcnkoZml0LjQpICNHYXJsaWMgbXVzdGFyZCBpbiB0aGUgbWFwbGUgdHJlYXRtZW50IGhhdmUgbGVzcyBvY2N1cmVuY2Ugb2YgZnVuZ2FsIGNvbG9uaXphdGlvbi4gCgpwbG90KGZpdC40KQpgYGAKCgoKI1Zpc3VhbGl6aW5nIC0tLSB0aGUgZGlzdHJpYnV0aW9uIG9mIHBhdGhvZ2VucyBieSB0cmVhdG1lbnQuIApgYGB7cn0KCnBsb3QyPC1kYXQyICU+JSBkcm9wX25hKEJsYWNrUGF0aERhbSkgJT4lIGdyb3VwX2J5KHRyZWF0bWVudCkgJT4lIHN1bW1hcml6ZShCbGFja1BhdGhBdmU9bWVhbihCbGFja1BhdGhEYW0sbmEucm09VCkpCgpwbG90MzwtZGF0MiAlPiUgZHJvcF9uYShUaHJpcHNEYW0pICU+JSBncm91cF9ieSh0cmVhdG1lbnQpICU+JSBzdW1tYXJpemUoVGhyaXBzRGFtPW1lYW4oVGhyaXBzRGFtLG5hLnJtPVQpKQoKcGxvdDQ8LWRhdDIgJT4lIGRyb3BfbmEoRmVybikgJT4lIGdyb3VwX2J5KHRyZWF0bWVudCkgJT4lIHN1bW1hcml6ZShGZXJuPW1lYW4oRmVybixuYS5ybT1UKSkKCgojQmxhY2sgUGF0aG9nZW4gYWJ1bmRhbmNlIGJ5IHRyZWFtdGVudApnZ3Bsb3QocGxvdDIpKwogIGdlb21fY29sKGFlcyh4PXRyZWF0bWVudCx5PUJsYWNrUGF0aEF2ZSxmaWxsPXRyZWF0bWVudCkpK3RoZW1lX3NpbXBsZSgpK3lsYWIoIkZ1bmdhbCBBYnVuZGFuY2VcbiAoJSBjb2xvbml6ZWQpIikreGxhYigiVHJlYXRtZW50IikrdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKI1RocmlwcyBhYnVuZGFuY2UgYnkgdHJlYXRtZW50LiAKZ2dwbG90KHBsb3QzKSsKICBnZW9tX2NvbChhZXMoeD10cmVhdG1lbnQseT1UaHJpcHNEYW0sZmlsbD10cmVhdG1lbnQpKSt0aGVtZV9zaW1wbGUoKSt5bGFiKCJGdW5nYWwgQWJ1bmRhbmNlXG4gKCUgY29sb25pemVkKSIpK3hsYWIoIlRyZWF0bWVudCIpK3RoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCiNJIHdvdWxkIG5lZWQgdG8gYWNjb3VudCBmb3IgdGhlIGdhcmxpYyBtdXN0YXJkIGJlaW5nIHBzdWVkb3JlcGxpY2F0ZWQgaXd0aCB0aGUgZmVybiBkYXRhLCBiZWNhdXNlIGVhY2ggZ20gaW4gdGhlIGdtIHRyZWF0bWVudCB3YXMgZ3Jvd24gd2l0aCBhbm90aGVyIGdtIGluIHRoZSBzYW1lIHBvdC4gCmdncGxvdChwbG90NCkrCiAgZ2VvbV9jb2woYWVzKHg9dHJlYXRtZW50LHk9RmVybixmaWxsPXRyZWF0bWVudCkpK3RoZW1lX3NpbXBsZSgpK3lsYWIoIkF2ZXJhZ2UgRmVybiBBYnVuZGFuY2UgKCNGZXJucy9wb3QpIikreGxhYigiVHJlYXRtZW50IikrdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsKICBzY2FsZV94X2Rpc2NyZXRlKG5hbWU9IiIsbGFiZWxzPWMoIkFsb25lIiwiR2FybGljIE11c3RhcmQiLCJNYXBsZSIpKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzAwOUU3MyIsIiM1NkI0RTkiLCIjRTY5RjAwIiksbGFiZWxzPWMoIkFsb25lIiwiR2FybGljIE11c3RhcmQiLCJNYXBsZSIpKSsKICB0aGVtZV9zaW1wbGVfbXVsdGlDb2woKSt0aGVtZShheGlzLnRpdGxlLnkgPSAgZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDE2LCBmYWNlID0gImJvbGQiLG1hcmdpbj1tYXJnaW4oMywyMCwzLDApKSkKI2Rldi5vZmYoKQoKCgpgYGAKCgojTW9kZWxsaW5nIC0tIFBvaXNzb24gLVdoYXQgaW5mbHVlbmNlcyBXaGl0ZSBwYXRob2dlbiBkYW1hZ2U/CmBgYHtyfQojUm91bmRpbmcgdG8gaW50ZWdlcnMgZm9yIHdoaXRlIGZ1bmcgZGFtLiAKZGF0JFdoaXRlRnVuZ0RhbTwtY2VpbGluZyhkYXQkV2hpdGVGdW5nRGFtKQoKZml0X2Z1bGw8LWdsbWVyKFdoaXRlRnVuZ0RhbX50cmVhdG1lbnQqZ2x1Y19Db25jK3RyZWF0bWVudCpmbGF2X0NvbmMrKDF8RmFtaWx5L1RhZykrKDF8Z2hfYmVuY2gpLGZhbWlseT1wb2lzc29uLGRhdGE9ZGF0KQoKZml0LjE8LXVwZGF0ZShmaXRfZnVsbCx+Li1mbGF2X0NvbmM6dHJlYXRtZW50KQphbm92YShmaXQuMSxmaXRfZnVsbCkgI0ZpdDEgaXMgYSBiZXR0ZXIgbW9kZWwKCgpmaXQuMjwtdXBkYXRlKGZpdC4xLH4uLWdsdWNfQ29uYzp0cmVhdG1lbnQpCmFub3ZhKGZpdC4yLGZpdC4xKSAjbW9kZWxzIGFyZSB0aGUgc2FtZS4uLiBlbGltaW5hdGluZyBpbnRlcmFjdGlvbi4KCmZpdC4zPC11cGRhdGUoZml0LjIsfi4tZ2x1Y19Db25jKQphbm92YShmaXQuMyxmaXQuMikgI1RoZSBtb2RlbCBpbmNsdWRpbmcgZ2x1Y0NvbmMgaXMgYmV0dGVyLiAKCmZpdC4yPC11cGRhdGUoZml0LjIsZGF0YT1kYXRbIWlzLm5hKGRhdCRmbGF2X0NvbmMpLF0pICNVc2luZyBhIG1vZGVsIHdpdGggYSBkYXRhIHN1YnNldC4KZml0LjM8LXVwZGF0ZShmaXQuMix+Li1mbGF2X0NvbmMpIAphbm92YShmaXQuMyxmaXQuMikjZmxhdl9Db25jIGlzIHVuaW1wb3J0YW50LCBldmVuIHRob3VnaCB0aGUgQUlDIGFuZCBCSUMgYXJlIGxvd2VyLgoKI1RoZXJlZm9yZSwgdGhlIGJlc3QgbW9kZWwgaXM6CnN1bW1hcnkoZ2xtZXIoV2hpdGVGdW5nRGFtfnRyZWF0bWVudCtnbHVjX0NvbmMrKDF8RmFtaWx5L1RhZykrKDF8Z2hfYmVuY2gpLGZhbWlseT1wb2lzc29uLGRhdGE9ZGF0KSkKCiN0aGUgaW5jbHVzaW9uIG9mIEdIX0JlbmNoIGRvZXMgbm90IGFmZmVjdCB0aGUgb3V0Y29tZSBvZiB0aGUgbW9kZWwsIHRoZXJlb2ZyZSwgSSBhbSBleGNsdWRpbmcgaXQgYXMgdGhlIG90aGVyIG1vZGVsIHdhcyBzYXR1cmF0ZWQgYW5kIHRvb2sgYWxvdCB0aW1lIHRvIGNvbXB1dGUuIApzdW1tYXJ5KGdsbWVyKFdoaXRlRnVuZ0RhbX50cmVhdG1lbnQrZ2x1Y19Db25jKygxfEZhbWlseS9UYWcpLGZhbWlseT1wb2lzc29uLGRhdGE9ZGF0KSkKI1VzaW5nIGEgUGVybXV0YXRpb24gdGVzdCB0byBkZXRlcm1pbmUgdGhlIHByb2JhYmlsaXR5IG9mIGdldHRpbmcgYSBzaWduaWZpY2FudCBnbHVjb3Npbm9sYXRlIGNvbmNlbnRyYXRpb24gcHJlZGljdG9yLCBpZiB0aGUgZGF0YSBpcyByYW1kb21seSBzYW1wbGVkLiAKCmRhdFBlclRlc3Q8LWRhdAp6U3RvcmU8LWMoKQojZm9yKGkgaW4gMToxMDAwKXsKICAjUmFuZG9taXplIGdsdWNvc2lub2xhdGUgY29uY2VudHJhdGlvbi4KICBkYXRQZXJUZXN0JGdsdWNfQ29uYzwtc2FtcGxlKGRhdCRnbHVjX0NvbmMsbGVuZ3RoKGRhdCRnbHVjX0NvbmMpLHJlcGxhY2UgPSBGKQogIAogICNSdW4gTW9kZWwgd2l0aCByYW5kb21pemVkIGdsdWNDb25jIGFuZCBleHRyYWN0IHAtdmFsdWUKICBnbHVjWnZhbDwtc3VtbWFyeShnbG1lcihXaGl0ZUZ1bmdEYW1+dHJlYXRtZW50K2dsdWNfQ29uYysoMXxGYW1pbHkvVGFnKSxmYW1pbHk9cG9pc3NvbixkYXRhPWRhdFBlclRlc3QpKSRjb2VmWzQsM10KCiAgI1N0b3JlIFAgdmFsdWUuCiAgelN0b3JlW2ldPC1nbHVjWnZhbAojfQoKI0hvdyBtYW55IHNhbXBsZXMgYXJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgWiBzY29yZSB0aGF0IGkgZ290PyAodGhlIHAgdmFsdWUpCnN1bSh6U3RvcmU8PS0zLjI2MikvbGVuZ3RoKHpTdG9yZSkKCiNUaGUgcCB2YWx1ZSBpcyBhY3R1YWxseSBhcm91bmQgLjEwLCB3aGljaCBpcyBub3Qgc2lnbmlmaWNhbnQuIEl0IHdhcyBlc3RpbWF0ZWQgdG8gYmUgMC4wMDEuIAoKI0dpdmVuIHRoYXQgNjQlIG9mIHRoZSBtb2RlbHMgcmV0dXJuIGEgc2lnbmlmaWNhbnQgcCB2YWx1ZSwgSSB3b3VsZCBzYXkgdGhhdCB0aGlzIGlzIGEgdmVyeSB2ZXJ5IHZlcnkgYmFkIG1vZGVsLiAKYGBgCgoKCgojVmlzdWFsbGl6aW5nIC0tIHdoaXRlIGZ1bmdhbCBkYW1hZ2UgaXMgaW5mbHVlbmNlZCBieSBnbHVjIGFuZCB0cmVhdG1uZXQuIApgYGB7cn0KClBvaXNTbG9wZT1mdW5jdGlvbih4LGludCl7CiAgeT1leHAoLTIuMzIyOTIqeCtpbnQpCiAgcmV0dXJuKHkpCn0KCmdsdWNwbG90PXNlcShtaW4oZGF0JGdsdWNfQ29uYyksbWF4KGRhdCRnbHVjX0NvbmMpLGxlbmd0aC5vdXQgPSA2OTUpCgpGdW5nQTwtUG9pc1Nsb3BlKGdsdWNwbG90LC0wLjE1NzAxKQpGdW5nTTwtUG9pc1Nsb3BlKGdsdWNwbG90LC0wLjE1NzAxLTAuODIwNjApCkZ1bmdHTTwtUG9pc1Nsb3BlKGdsdWNwbG90LC0wLjE1NzAxKzAuMDI0ODMpCgpmaXQuZzwtZ2xtKFdoaXRlRnVuZ0RhbX5nbHVjX0NvbmMrdHJlYXRtZW50LGZhbWlseT1wb2lzc29uLGRhdGE9ZGF0KQpzdW1tYXJ5KGZpdC5nKQoKcHJlZGljdChmaXQuZyx0eXBlPSJyZXNwb25zZSIsbmV3ZGF0YT1kYXRhLmZyYW1lKCJ0cmVhdG1lbnQiPXJlcCgiYSIsNjk1KSwiZ2x1Y19Db25jIj1nbHVjcGxvdCkpCgpkYXR2PC1kYXRbIWlzLm5hKGRhdCRXaGl0ZUZ1bmdEYW0pLF0KCiN0aWZmKCJEZWZlbmNlX0ZpZ3VyZXMvR2x1Y29zaW5vbGF0ZUZ1bmdpLnRpZmYiLCB1bml0cz0iaW4iLCB3aWR0aD0xMCwgaGVpZ2h0PTYsIHJlcz0zMDApCmdncGxvdChkYXR2W2RhdHYkV2hpdGVGdW5nRGFtPDMwLF0pKwogIGdlb21fcG9pbnQoYWVzKHk9V2hpdGVGdW5nRGFtLHg9Z2x1Y19Db25jLGNvbG91cj10cmVhdG1lbnQpKSsKICAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPWMoIiMwMDlFNzMiLCIjNTZCNEU5IiwiI0U2OUYwMCIsIiMwMDlFNzMiLCIjNTZCNEU5IiwiI0U2OUYwMCIpLGxhYmVscz1jKCJBbG9uZSIsIkdhcmxpYyBNdXN0YXJkIiwiTWFwbGUiKSkrdGhlbWVfc2ltcGxlKCkrCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1jKDAsMiw0LDYsOCwxMCwxMikpKwogIGdlb21fcGF0aCh4PWdsdWNwbG90LHk9RnVuZ0EsY29sb3VyPSIjMDA5RTczIikrCiAgZ2VvbV9wYXRoKHg9Z2x1Y3Bsb3QseT1GdW5nTSxjb2xvdXI9IiNFNjlGMDAiKSsKICB5bGFiKCJQb3dkZXJ5IE1pbGRldyBEYW1hZ2UiKSsKeGxhYihicXVvdGUoYm9sZCgiW1RvdGFsIEdsdWNvc2lub2xhdGVdICIgKG1nL21sKSkpKQojZGV2Lm9mZigpCgpgYGAKCgojTW9kZWxsaW5nIC0tIFdoYXQgaW5mbHVlbmNlcyBCbGFjayBQYXRob2dlbiBEYW1hZ2U/IC0tKHJlZG8gbmV3IGRhdGEpCmBgYHtyfQpkYXQkQmxhY2tQYXRoRGFtCmRhdCRCbGFja1BhdGhEYW08LWNlaWxpbmcoZGF0JEJsYWNrUGF0aERhbSkKI0dsdWNvc2lub2xhdGUgYW5kIGZsYXZvbm9pZHMgYXJlIGNvcnJlbGF0ZWQsIGJ1dCB0aGUgUjIgaXMgb25seSAwLjM5LCBzbyBpIGRvbnQgdGhpbmsgaXQgaXMgYSB2ZXJ5IGJpZyBkZWFsLiAKc3VtbWFyeShsbShnbHVjX0NvbmN+Zmxhdl9Db25jLGRhdD1kYXQpKQoKZml0X2Z1bGw8LWdsbWVyKEJsYWNrUGF0aERhbX50cmVhdG1lbnQqZ2x1Y19Db25jK3RyZWF0bWVudCpmbGF2X0NvbmMrKDF8RmFtaWx5L1RhZykrKDF8Z2hfYmVuY2gpLGZhbWlseT1wb2lzc29uLGRhdGE9ZGF0KQoKZml0LjE8LXVwZGF0ZShmaXRfZnVsbCx+Li1mbGF2X0NvbmM6dHJlYXRtZW50KQphbm92YShmaXQuMSxmaXRfZnVsbCkgI1RoZXJlIGlzIGEgc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gYmV0d2VlbiBmbGF2IGNvbmNlbnRyYXRpb24gYW5kIHRyZWF0bWVudC4gCgpmaXQuMjwtdXBkYXRlKGZpdF9mdWxsLH4uLWdsdWNfQ29uYzp0cmVhdG1lbnQpCmFub3ZhKGZpdC4yLGZpdF9mdWxsKSAjVGhlcmUgaXMgYWxzbyBhIHNpZ25pZmljYW50IGludGVyYWN0aW9uIGJldHdlZW4gZ2x1YyBDb25jIGFuZCB0cmVhdG1lbnQuIAoKI0RpYWdub3N0aWMKCgpwbG90KGZpdF9mdWxsKQoKCiNQZXJtdXRhdGlvbiB0ZXN0LiAKZGF0UGVyVGVzdDwtZGF0Cm5ld2ZyYW1lPC1OQQpmb3IoaSBpbiAxOjMwMCl7CiAgI1JhbmRvbWl6ZSBnbHVjb3Npbm9sYXRlIGNvbmNlbnRyYXRpb24uCiAgZGF0UGVyVGVzdCRmbGF2X0NvbmM8LXNhbXBsZShkYXQkZmxhdl9Db25jLGxlbmd0aChkYXQkZmxhdl9Db25jKSxyZXBsYWNlID0gRikKICBkYXRQZXJUZXN0JGdsdWNfQ29uYzwtc2FtcGxlKGRhdCRnbHVjX0NvbmMsbGVuZ3RoKGRhdCRnbHVjX0NvbmMpLHJlcGxhY2UgPSBGKQogIGRhdFBlclRlc3QkdHJlYXRtZW50PC1zYW1wbGUoZGF0JHRyZWF0bWVudCxsZW5ndGgoZGF0JHRyZWF0bWVudCkscmVwbGFjZSA9IEYpCgogICNSdW4gTW9kZWwgd2l0aCByYW5kb21pemVkIGdsdWNDb25jIGFuZCBleHRyYWN0IHAtdmFsdWUKICBNb2RlbFp2YWw8LXN1bW1hcnkoZ2xtZXIoQmxhY2tQYXRoRGFtfnRyZWF0bWVudCpnbHVjX0NvbmMrdHJlYXRtZW50KmZsYXZfQ29uYysoMXxGYW1pbHkvVGFnKSxmYW1pbHk9cG9pc3NvbixkYXRhPWRhdFBlclRlc3QpKSRjb2VmWywzXQogIAogICNTYXZpbmcgYWxsIG9mIHRoZSBaIHZhbHVlcyBpbiBhIGRhdGFmcmFtZS4gCiAgbmV3ZnJhbWU8LXJiaW5kKG5ld2ZyYW1lLE1vZGVsWnZhbCkKfQoKbmV3ZnJhbWU8LWRhdGEuZnJhbWUobmV3ZnJhbWUpCnN1bW1hcnkoZml0X2Z1bGwpCm5ld2ZyYW1lCnN1bW1hcnkoZml0X2Z1bGwpJGNvZWZbMSwzXQpzdW0obmV3ZnJhbWVbLDFdPD0tMS4zNSxuYS5ybSA9IFQpL2xlbmd0aChuZXdmcmFtZVssMV0pCgojRmxhdm9ub2lkIGNvbmNlbnRyYXRpb24gaW50ZXJhY3Rpb24gaXMgbm90IHNpZ25pZmljYW50LiBNdXN0IGJlIGxlc3MgdGhhbiAwLjI1LiBUaGlzIGlzIGEgcG9vciBtb2RlbCBmb3IgdGhpcyBkYXRhLiAKc3VtKG5ld2ZyYW1lJGZsYXZfQ29uYzw9LTUuMjIwLG5hLnJtID0gVCkvbGVuZ3RoKG5ld2ZyYW1lJGZsYXZfQ29uYykKCiNUaGlzIGFzIHdlbGwgaXMgbm90IHNpZ25pZmljYW50LiAKc3VtKG5ld2ZyYW1lJGdsdWNfQ29uYz49My42MDUgLG5hLnJtID0gVCkvbGVuZ3RoKG5ld2ZyYW1lJGdsdWNfQ29uYykKCiNUaGUgcCB2YWx1ZSBjYWxjdWxhdGVkIGZvciB0aGlzIG5vdCBhY3R1YWxseSBjbG9zZSB0byB6ZXJvIGFzIGluIHRoZSBtb2RlbCwgYnV0IGlzIGFyb3VuZCAwLjE1MzMzMzMuIFRoaXMgaXMgbm90IHNpZ25pZmljYW50LiAKI0FwcHJveGltaXRlbHkgaGFsZiBvZiB0aGUgcCB2YWx1ZXMgYXJlIGxlc3MgdGhhbiAwLjA1LCB0aGlzIHN1Z2dlc3RzIHRoYXQgdGhpcyBtb2RlbCBpcyBxdWl0ZSBob3JyaWJsZS4gCgpgYGAKCiNWaXN1YWxsaXppbmcgLS0gQmxhY2sgUGF0aG9nZW4gZGFtYWdlIGlzIGluZmx1ZW5jZWQgYnkgZmxhdm9ub2lkcy4gCmBgYHtyfQoKClBvaXNTbG9wZT1mdW5jdGlvbih4KXsKICB5PWV4cCgtMS4xMTUwKngrMS42ODE2KQogIHJldHVybih5KQp9CgoKZmxhdnBsb3Q9c2VxKG1pbihkYXQkZmxhdl9Db25jLG5hLnJtID0gVCksbWF4KGRhdCRmbGF2X0NvbmMsbmEucm09VCksbGVuZ3RoLm91dCA9IDY4NykKCmZsYXZ5PC1Qb2lzU2xvcGUoZmxhdnBsb3QpCgojdGlmZigiRGVmZW5jZV9GaWd1cmVzL0ZsYXZvbm9pZEJsYWNrUGF0aC50aWZmIiwgdW5pdHM9ImluIiwgd2lkdGg9MTAsIGhlaWdodD02LCByZXM9MzAwKQpnZ3Bsb3QoZGF0WyFpcy5uYShkYXQkZmxhdl9Db25jKSYhaXMubmEoZGF0JGZsYXZfQ29uYyksXSkrCiAgZ2VvbV9wb2ludChhZXMoeT1CbGFja1BhdGhEYW0seD1mbGF2X0NvbmMpKSt0aGVtZV9zaW1wbGUoKSsKICBnZW9tX3BhdGgoeD1mbGF2cGxvdCx5PWZsYXZ5LHNpemU9MSxjb2xvdXI9IiM5OTk5OTkiKSsKICAKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPWMoMCw1LDEwLDE1LDIwLDI1LDMwKSkrCiAgeWxhYigiQmxhY2sgUGF0aG9nZW4gRGFtYWdlIikrCnhsYWIoYnF1b3RlKGJvbGQoIltUb3RhbCBGbGF2b25vaWRdICIgKG1nL21sKSkpKQojZGV2Lm9mZigpCgpgYGAKCgojV2hhdCBpbmZsdWVuY2VzIFRocmlwcyBkYW1hZ2U/IC0tKHJlZG8gbmV3IGRhdGEpCmBgYHtyfQojR2x1Y29zaW5vbGF0ZSBhbmQgZmxhdm9ub2lkcyBhcmUgY29ycmVsYXRlZCwgYnV0IHRoZSBSMiBpcyBvbmx5IDAuMzksIHNvIGkgZG9udCB0aGluayBpdCBpcyBhIHZlcnkgYmlnIGRlYWwuIApzdW1tYXJ5KGxtKGdsdWNfQ29uY35mbGF2X0NvbmMsZGF0PWRhdCkpCgpmaXRfZnVsbDwtZ2xtZXIoVGhyaXBzRGFtfnRyZWF0bWVudCtnbHVjX0NvbmMrZmxhdl9Db25jKygxfEZhbWlseS9UYWcpKygxfGdoX2JlbmNoKSxmYW1pbHk9cG9pc3NvbixkYXRhPWRhdCkKCmZpdC4xPC11cGRhdGUoZml0X2Z1bGwsfi4tZ2x1Y19Db25jKQphbm92YShmaXQuMSxmaXRfZnVsbCkgI0dsdWMgQ29uYyBpcyBpbiBubyB3YXkgYSBzaWduaWZpY2FudCBwcmVkaWN0b3IuIAoKCmZpdC4yPC11cGRhdGUoZml0LjEsfi4tdHJlYXRtZW50KQphbm92YShmaXQuMSxmaXQuMikgI3RyZWF0bWVudCBpcyBub3QgYSBzaWduaWZpY2FudCBwcmVkaWN0b3IuIAoKCmZpdC4yPC11cGRhdGUoZml0LjIsZGF0YT1kYXRbIWlzLm5hKGRhdCRmbGF2X0NvbmMpLF0pI0NoYW5naW5nIGRhdGEgc2V0IHRvIGFjY291bnQgZm9yIG1pc3NpbmcgZmxhdm9ub2lkIGRhdGEuIApmaXQuMzwtdXBkYXRlKGZpdC4yLH4uLWZsYXZfQ29uYykKYW5vdmEoZml0LjMsZml0LjIpICNUaGVyZSBpcyBubyBkaWZmZXJlbmNlIGluIGEgbW9kZWwgd2l0aCBhbmQgd2l0aG91dCBnbHVjX0NvbmMuIFRoZXJlZm9yZSwgaXQgaXMgcmVtb3ZlZC4gCgpmaXQuMzwtdXBkYXRlKGZpdC4zLGRhdGE9ZGF0WyFpcy5uYShkYXQkZmxhdl9Db25jKSxdKSAjVXNpbmcgYSBtb2RlbCB3aXRoIGEgZGF0YSBzdWJzZXQuCmZpdC40PC11cGRhdGUoZml0LjMsfi4tZmxhdl9Db25jKSAKYW5vdmEoZml0LjQsZml0LjMpI2ZsYXZfQ29uYyBpcyB2ZXJ5IHNpZ25pZmljYW50LktlZXBpbmcgdGhpcyBpbiB0aGUgbW9kZWwuCgoKZ2dwbG90KGRhdCkrCiAgZ2VvbV9wb2ludChhZXMoeT1UaHJpcHNEYW0seD1mbGF2X0NvbmMpKQoKZml0LjQ8LWdsbWVyKFRocmlwc0RhbX5mbGF2X0NvbmMrKDF8RmFtaWx5L1RhZykrKDF8Z2hfYmVuY2gpLGZhbWlseT1wb2lzc29uLGRhdGE9ZGF0KQoKc3VtbWFyeShmaXQuNCkgI0ZsYXYgY29uYyBpcyBhZ2FpbiwgYSB2ZXJ5IHNpZ25pZmljYW50IHByZWRpY3Rvci4gCgoKCiNQZXJtdXRhdGlvbiB0ZXN0LiAKZGF0JFRocmlwc0RhbTwtY2VpbGluZyhkYXQkVGhyaXBzRGFtKQpkYXRQZXJUZXN0PC1kYXQKelN0b3JlPC1jKCkKZm9yKGkgaW4gMToxMDAwKXsKICAjUmFuZG9taXplIGdsdWNvc2lub2xhdGUgY29uY2VudHJhdGlvbi4KICBkYXRQZXJUZXN0JGZsYXZfQ29uYzwtc2FtcGxlKGRhdCRmbGF2X0NvbmMsbGVuZ3RoKGRhdCRmbGF2X0NvbmMpLHJlcGxhY2UgPSBGKQogIAogICNSdW4gTW9kZWwgd2l0aCByYW5kb21pemVkIGdsdWNDb25jIGFuZCBleHRyYWN0IHAtdmFsdWUKICBmbGF2WnZhbDwtc3VtbWFyeShnbG1lcihUaHJpcHNEYW1+Zmxhdl9Db25jKygxfEZhbWlseS9UYWcpLGZhbWlseT1wb2lzc29uLGRhdGE9ZGF0UGVyVGVzdCkpJGNvZWZbMiwzXQogIAogICNTdG9yZSBQIHZhbHVlLgogIHpTdG9yZVtpXTwtZmxhdlp2YWwKfQoKc3VtKHpTdG9yZTw9LTE4LjcxKS9sZW5ndGgoelN0b3JlKQoKaGlzdCh6U3RvcmUpCiNUaGUgcCB2YWx1ZSBmb3IgdGhpcyBtb2RlbCBpcyBzdGlsbCBhYm91dCB6ZXJvIGFjY29yZGluZyB0byB0aGUgcGVybXV0YXRpb24gdGVzdCwgd2hpY2ggbWlnaHQgc3VnZ2VzdCB0aGF0IGl0IGlzIGEgYmV0dGVyIG1vZGVsIHRoYW4gdGhlIG90aGVycy4gCgpwbG90KGZpdC40KQoKYGBgCgojVmlzdWFsaXppbmcgLSBpbmZsdWVuY2Ugb2YgZmxhdm9ub2lkcyBvbiB0aHJpcHMgZGFtYWdlLiAKYGBge3J9CgpQb2lzU2xvcGU9ZnVuY3Rpb24oeCl7CiAgeT1leHAoLTIuMzMxOSp4KzMuNTI0OSkKICByZXR1cm4oeSkKfQoKCmZsYXZwbG90PXNlcShtaW4oZGF0JGZsYXZfQ29uYyxuYS5ybSA9IFQpLG1heChkYXQkZmxhdl9Db25jLG5hLnJtPVQpLGxlbmd0aC5vdXQgPSA2ODcpCgpmbGF2eTwtUG9pc1Nsb3BlKGZsYXZwbG90KQoKI3RpZmYoIkRlZmVuY2VfRmlndXJlcy9GbGF2b25vaWRUaHJpcHMudGlmZiIsIHVuaXRzPSJpbiIsIHdpZHRoPTEwLCBoZWlnaHQ9NiwgcmVzPTMwMCkKZ2dwbG90KGRhdFshaXMubmEoZGF0JGZsYXZfQ29uYykmIWlzLm5hKGRhdCRmbGF2X0NvbmMpLF0pKwogIGdlb21fcG9pbnQoYWVzKHk9VGhyaXBzRGFtLHg9Zmxhdl9Db25jKSkrdGhlbWVfc2ltcGxlKCkrCiAgZ2VvbV9wYXRoKHg9ZmxhdnBsb3QseT1mbGF2eSxzaXplPTEsY29sb3VyPSIjOTk5OTk5IikrCiAgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcz1jKDAsNSwxMCwxNSwyMCwyNSwzMCwzNSw0MCkpKwogIHlsYWIoIlRocmlwcyBEYW1hZ2UiKSsKeGxhYihicXVvdGUoYm9sZCgiW1RvdGFsIEZsYXZvbm9pZF0gIiAobWcvbWwpKSkpCiNkZXYub2ZmKCkKCmBgYAoKCgoKI1Zpc3VhbGl6aW5nIC0tIGVmZmVjdCBvZiBmbGF2b25vaWRzIG9uIGZlcm4gYWJ1bmRhbmNlLiAKYGBge3J9CgpQb2lzU2xvcGU9ZnVuY3Rpb24oeCxpbnQpewogIHk9ZXhwKCgtMC4wMjM1MyAtMy4xMjQ3NSkqeCtpbnQpCiAgcmV0dXJuKHkpCn0KZXhwKC0wLjY1NzEpCgpmbGF2cGxvdD1zZXEobWluKGRhdCRmbGF2X0NvbmMsbmEucm0gPSBUKSxtYXgoZGF0JGZsYXZfQ29uYyxuYS5ybT1UKSxsZW5ndGgub3V0ID0gNzA3KQoKZmxhdnlBPC1Qb2lzU2xvcGUoZmxhdnBsb3QsLTIuMTY4MykKZmxhdnlNPC1Qb2lzU2xvcGUoZmxhdnBsb3QsLTEuNjA1NDYtMi44MTQ1MCkKZmxhdnlHTTwtUG9pc1Nsb3BlKGZsYXZwbG90LC0yLjE2ODMtMC4yNzg2KQoKCiN0aWZmKCJEZWZlbmNlX0ZpZ3VyZXMvRmxhdm9ub2lkRmVybi50aWZmIiwgdW5pdHM9ImluIiwgd2lkdGg9MTAsIGhlaWdodD02LCByZXM9MzAwKQpnZ3Bsb3QoZGF0KSsKICBnZW9tX3BvaW50KGFlcyh5PUZlcm4seD1mbGF2X0NvbmMsY29sb3VyPXRyZWF0bWVudCkpK3RoZW1lX3NpbXBsZSgpKwogIyBnZW9tX3BhdGgoeD1mbGF2cGxvdCx5PWZsYXZ5QSxzaXplPTEsY29sb3VyPSIjMDA5RTczIikKICAjZ2VvbV9wYXRoKHg9ZmxhdnBsb3QseT1mbGF2eUdNLHNpemU9MSxjb2xvdXI9IiM1NkI0RTkiKQogIGdlb21fcGF0aCh4PWZsYXZwbG90LHk9ZmxhdnlNLHNpemU9MSxjb2xvdXI9IiNFNjlGMDAiKSsKICAgICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9YygiIzAwOUU3MyIsIiM1NkI0RTkiLCIjRTY5RjAwIiksbGFiZWxzPWMoIkFsb25lIiwiR2FybGljIE11c3RhcmQiLCJNYXBsZSIpKSsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPWMoMCw1LDEwLDE1LDIwLDI1LDMwLDM1LDQwKSkrCiAgeWxhYigiRmVybiBBYnVuZGFuY2UiKSsKeGxhYihicXVvdGUoYm9sZCgiW1RvdGFsIEZsYXZvbm9pZF0gIiAobWcvbWwpKSkpCiNkZXYub2ZmKCkKCmBgYAoKSG93IGNhbiB3ZSBrbm93IHRoYXQgaGVhbHRoeSBwbGFudHMgZG9udCBqdXN0IGV4aGliaXQgbW9yZSBzZWNvbmRhcnkgY29tcG91bmRzIGFuZCBub3QgdGhhdCB0aG9zZSB3aXRoIG1vcmUgc2Vjb25kYXJ5IGNvbXBvdW5kcyBhcmUgaGVhbHRoaWVyPwoKCgoKCg==